Lecture 07
Lecture 07
Dictionaries
Updating collections
• There are three ways to deal with operations that update collections:
- Returns an updated copy of the collection
- Updates the collection in place
- Updates the collection in place and returns it
• list.sort and list.reverse work in place and don't return it
• sorted and reversed return an updated copy
- reversed actually returns an iterator
- these also work for immutable sequences like strings and tuples
Scope
• The scope of a variable refers to where in a program it can be referenced
• Python has three scopes:
- global: de ned outside a function
- local: in a function, only valid in the function
- nonlocal: can be used with nested functions
• Python allows variables in different scopes to have the same name
Global keyword
• def f(): # no arguments • def f(): # no arguments
x = 2 global x
print("x inside:", x) x = 2
print("x inside:", x)
x = 1
f() x = 1
print("x outside:", x) f()
print("x outside:", x)
• Output:
- x inside: 2 • Output:
x outside: 1 - x inside: 2
x outside: 2
Is Python pass-by-value or pass-by-reference?
Pass by object reference
• AKA passing object references by value
• Python doesn't allocate space for a variable, it just links identi er to a value
• Mutability of the object determines whether other references see the change
• Any immutable object will act like pass by value
• Any mutable object acts like pass by reference unless it is reassigned to a
new value
fi
Assignment 2
• Due Thursday
• Python control ow and functions
• Do not use containers like lists!
• Compute orbit and number of steps for mathematical sequences
• Make sure to follow instructions
- Name the submitted le a2.ipynb
- Put your name and z-id in the rst cell
- Label each part of the assignment using markdown
- Make sure to produce output according to speci cations
fl
fi
fi
fi
a_list = [0,1,2,3,4]
change_list()
a_list # [10,9,8,7,6]
Use None as a default instead
• def append_to(element, to=None):
if to is None:
to = []
to.append(element)
return to
• my_list = append_to(12)
my_list # [12]
• my_other_list = append_to(42)
my_other_list # [42]
Keyword Arguments
• Keyword arguments allow someone calling a function to specify exactly
which values they wish to specify without specifying all the values
• This helps with long parameter lists where the caller wants to only change a
few arguments from the defaults
• def f(alpha=3, beta=4, gamma=1, delta=7, epsilon=8, zeta=2,
eta=0.3, theta=0.5, iota=0.24, kappa=0.134):
# …
• f(beta=12, iota=0.7)
Positional & Keyword Arguments
• Generally, any argument can be passed as a keyword argument
• def f(alpha, beta, gamma=1, delta=7, epsilon=8, zeta=2,
eta=0.3, theta=0.5, iota=0.24, kappa=0.134):
# …
• f(5,6)
• f(alpha=7, beta=12, iota=0.7)
Position-Only Arguments
• PEP 570 introduced position-only arguments
• Sometimes it makes sense that certain arguments must be position-only
• Certain functions (those implemented in C) only allow position-only: pow
• Add a slash (/) to delineate where keyword arguments start
• def f(alpha, beta, /, gamma=1, delta=7, epsilon=8, zeta=2,
eta=0.3, theta=0.5, iota=0.24, kappa=0.134):
# …
- f(alpha=7, beta=12, iota=0.7) # ERROR
- f(7, 12, iota=0.7) # WORKS
Arbitrary Argument Containers
• def f(*args, **kwargs):
# …
• args: a list of arguments
• kwargs: a key-value dictionary of arguments
• Stars in function signature, not in use
• Can have named arguments before these arbitrary containers
• Any values set by position will not be in kwargs:
• def f(a, *args, **kwargs):
print(args)
print(kwargs)
f(a=3, b=5) # args is empty, kwargs has only b
fi
fi
Dictionaries
Dictionary Examples
Mutability
• Dictionaries are mutable, key-value pairs can be added, removed, updated
• (Each key must be immutable)
• Accessing elements parallels lists but with different "indices" possible
• Index → Key
• d = {'DeKalb': 783, 'Kane': 134, 'Cook': 1274, 'Will': 546}
• d['Winnebago'] = 1023 # add a new key-value pair
• d['Kane'] = 342 # update an existing key-value pair
• d.pop('Will') # remove an existing key-value pair
• del d['Winnebago'] # remove an existing key-value pair
Key Restrictions
• Many types can be keys… including tuples
- d = {'abc': 25, 12: 'abc', ('Kane', 'IL'): 123.54}
• …but the type must be immutable—lists cannot be keys
- d = {['Kane', 'IL']: 2348.35, [1, 2, 3]: "apple"}
• Why?
Key Restrictions
• Many types can be keys… including tuples
- d = {'abc': 25, 12: 'abc', ('Kane', 'IL'): 123.54}
• …but the type must be immutable*—lists cannot be keys
- d = {['Kane', 'IL']: 2348.35, [1, 2, 3]: "apple"}
• *technically, the type must be hashable, but having a mutable and still hashable type almost always causes problems
• Why?
- Dictionaries are fast in Python because are implemented as hash tables
- No matter how long the key, python hashes it stores values by hash
- Given a key to lookup, Python hashes it and nds the value quickly (O(1))
- If the key can mutate, the hash will not match the key!
fi
Principle
• Be careful using oats for keys
• Why?
Principle
• Be careful using oats for keys
• a = 0.123456
b = 0.567890
values = [a, b, (a / b) * b, (b / a) * a]
found = {}
for d in values:
found[d] = True
len(found) # 3 !!!
found.keys() # [0.123456, 0.56789, 0.12345599999999998]
Accessing Values by Key
• To get a value, we start with a key
• Things work as expected
- d['Kane'] + d['Cook']
• If a value does not exist, get KeyError
- d['Boone'] > 12 # KeyError
Membership
• The membership operator (in) applies to keys
- 'Boone' in d # False
- 'Cook' in d # True
• To check the negation (if a key doesn't exist), use not in
- 'Boone' not in d # True
- not 'Boone' in d # True (equivalent but less readable)
• Membership testing is much faster than for a list
• Checking and accessing at once
- d.get('Boone') # no error, evaluates to None
- d.get('Boone', 0) # no error, evaluates to 0 (default)
Dictionary Methods
Method Meaning
<dict>.clear() Remove all key-value pairs
<dict>.update(other) Updates the dictionary with values from other
<dict>.pop(k, d=None) Removes the pair with key k and returns value or
default d if no key
<dict>.get(k, d=None) Returns the value for the key k or default d if no
key
<dict>.items() Returns iterable view over all pairs as (key, value)
tuples
<dict>.keys() Returns iterable view over all keys
<dict>.values() Returns iterable view over all values
D. Koop, CSCI 503/490, Spring 2023 33
Dictionary Methods
Method Meaning Mutate
<dict>.clear() Remove all key-value pairs
<dict>.update(other) Updates the dictionary with values from other
<dict>.pop(k, d=None) Removes the pair with key k and returns value or
default d if no key
<dict>.get(k, d=None) Returns the value for the key k or default d if no
key
<dict>.items() Returns iterable view over all pairs as (key, value)
tuples
<dict>.keys() Returns iterable view over all keys
<dict>.values() Returns iterable view over all values
D. Koop, CSCI 503/490, Spring 2023 33