Containers Announcements
Replacing Iteration with Recursion
You can convert while/for statements to recursion without inventing new logic:
• Each pass through the body of a while/for statement is replaced by a recursive call.
• Instead of using assignment statements, assign names to values using a call expression.
• If needed, introduce a new function with an argument for every value that must be tracked.
Iteration and Recursion
(Demo)
4
The Closure Property of Data Types
• A method for combining data values satisfies the closure property if:
The result of combination can itself be combined using the same method
• Closure is powerful because it permits us to create hierarchical structures
Box-and-Pointer Notation • Hierarchical structures are made up of parts, which themselves are made up
of parts, and so on
Lists can contain lists as elements (in addition to anything else)
Box-and-Pointer Notation in Environment Diagrams Box-and-Pointer Notation in Environment Diagrams
Lists are represented as a row of index-labeled adjacent boxes, one per element Lists are represented as a row of index-labeled adjacent boxes, one per element
Each box either contains a primitive value or points to a compound value Each box either contains a primitive value or points to a compound value
7 8
pythontutor.com/composingprograms.html#code=pair%20%3D%20[1,%202]%0A%0Anested_list%20%3D%20[[1,%202],%20[],%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20[[3,%20False,%20None],
%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20[4,%20lambda%3A%205]]]&mode=display&origin=composingprograms.js&cumulative=true&py=3&rawInputLstJSON=[]&curInstr=4
Slicing Creates New Values
Slicing Creates Lists
10
pythontutor.com/composingprograms.html#code=digits%20%3D%20[1,%208,%202,%208]%0Astart%20%3D%20digits[%3A1]%0Amiddle%20%3D%20digits[1%3A3]%0Aend%20%3D%20digits[2%3A]%0Afull%20%3D%20digits[%3A]&cumulative%3Dtrue&curInstr%3D5&mode=display&origin=composingprograms.js&py=3&rawInputLstJSON=[]
Aggregation
Several built-in functions take iterable arguments and aggregate them into a value
• sum(iterable[, start]) -> value
Return the sum of an iterable (not of strings) plus the value
of parameter 'start' (which defaults to 0). When the iterable is
empty, return start.
Processing Container Values
• max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value
With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.
(Demo) • all(iterable) -> bool
Return True if bool(x) is True for all values x in the iterable.
If the iterable is empty, return True.
12
Discussion Question
Find the power of 2 that is closest to 1,000 using one line:
(You can assume that it's smaller than 2 ** 100.)
Strings
2 ** n for n in range(100) lambda x: abs(1000 - x)
min( [ ___________________________ ], key= _________________________ )
13
Strings are an Abstraction String Literals Have Three Forms
Representing data: >>> 'I am string!'
'I am string!'
'200' '1.2e-5' 'False' '[1, 2]' >>> "I've got an apostrophe" Single-quoted and double-quoted
"I've got an apostrophe" strings are equivalent
Representing language:
>>> '您好'
"""And, as imagination bodies forth '您好'
The forms of things unknown, the poet's pen
Turns them to shapes, and gives to airy nothing >>> """The Zen of Python
A local habitation and a name. claims, Readability counts.
""" Read more: import this."""
'The Zen of Python\nclaims, Readability counts.\nRead more: import this.'
Representing programs:
A backslash "escapes" the "Line feed" character
'curry = lambda f: lambda x: lambda y: f(x, y)'
following character represents a new line
(Demo)
15 16
Limitations on Dictionaries
Dictionaries are collections of key-value pairs
Dictionary keys do have two restrictions:
• A key of a dictionary cannot be a list or a dictionary (or any mutable type)
Dictionaries
• Two keys cannot be equal; There can be at most one value for a given key
This first restriction is tied to Python's underlying implementation of dictionaries
The second restriction is part of the dictionary abstraction
{'Dem': 0} If you want to associate multiple values with a key, store them all in a sequence value
18
Dictionary Comprehensions Example: Indexing
{<key exp>: <value exp> for <name> in <iter exp> if <filter exp>} Implement index, which takes a sequence of keys, a sequence of values, and a two-argument
match function. It returns a dictionary from keys to lists in which the list for a key k
contains all values v for which match(k, v) is a true value.
Short version: {<key exp>: <value exp> for <name> in <iter exp>}
def index(keys, values, match):
An expression that evaluates to a dictionary using this evaluation procedure:
"""Return a dictionary from keys k to a list of values v for which
1. Add a new frame with the current frame as its parent match(k, v) is a true value.
2. Create an empty result dictionary that is the value of the expression >>> index([7, 9, 11], range(30, 50), lambda k, v: v % k == 0)
{7: [35, 42, 49], 9: [36, 45], 11: [33, 44]}
3. For each element in the iterable value of <iter exp>: """
{k: [v for v in values if match(k, v)] for k in keys}
A. Bind <name> to that element in the new frame from step 1 return __________________________________________________________
B. If <filter exp> evaluates to a true value, then add to the result dictionary
an entry that pairs the value of <key exp> to the value of <value exp>
{x * x: x for x in [1, 2, 3, 4, 5] if x > 2} evaluates to {9: 3, 16: 4, 25: 5}
19 20