Comprehensions and Generators Flashcards
(31 cards)
map(function, iterable, …)
Return an iterator that applies function to every item of iterable, yielding the results.
If additional iterable arguments are passed, function must take that many arguments
and is applied to the items from all iterables in parallel.
> list(map(lambda *a: a, range(3), ‘abc’))
# 2 iterables
[(0, ‘a’), (1, ‘b’), (2, ‘c’)]
list(map(lambda *a: a, (1, 2), ‘abc’))
# (1, 2) shortest
[(1, ‘a’), (2, ‘b’)]
map() stops when the ____ o the iterable we call it with is exhausted
shortest
zip(*iterables)
Returns an iterator of tuples, where the i-th tuple contains the i-th element from
each of the argument sequences or iterables. The iterator stops when the shortest
input iterable is exhausted. With a single iterable argument, it returns an iterator
of 1-tuples. With no arguments, it returns an empty iterator.
> > > grades = [18, 23, 30, 27]
avgs = [22, 21, 29, 24]
list(zip(avgs, grades))
[(22, 18), (21, 23), (29, 30), (24, 27)]
> > > list(map(lambda *a: a, avgs, grades))
[(22, 18), (21, 23), (29, 30), (24, 27)]
filter(function, iterable)
Construct an iterator from those elements of iterable for which function returns
True. iterable may be either a sequence, a container which supports iteration, or an
iterator. If function is None, the identity function is assumed, that is, all elements
of iterable that are false are removed.
> > > test = [2, 5, 8, 0, 0, 1, 0]
list(filter(None, test))
er(None, test))
[2, 5, 8, 1]
> > > list(filter(lambda x: x > 4, test)) # keep only items > 4
[5, 8]
> > > squares = map(lambda n: n**2, range(10))
list(squares)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
LIST COMPREHENSION
»> [n ** 2 for n in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
filter passes each element in the iterable through func and return only the ones that evaluate to ____
true
what prints?
sq1 = list(
map(lambda n: n ** 2, filter(lambda n: not n % 2, range(10)))
)
# equivalent, but using list comprehensions
sq2 = [n ** 2 for n in range(10) if not n % 2]
print(sq1, sq1 == sq2)
prints: [0, 4, 16, 36, 64] True
You can also use nested comprehension in place of ____ loop
nested
for a in range(len(items)):
for b in range(a, len(items)):
pairs.append((items[a], items[b]))
What is the equivalent nested comprehension
items = ‘ABCD’
pairs = [(items[a], items[b])
for a in range(len(items)) for b in range(a, len(items))]
We can also apply filtering to a comprehension
Example
from math import sqrt
# this will generate all possible pairs
mx = 10
triples = [(a, b, sqrt(a2 + b2))
for a in range(1, mx) for b in range(a, mx)]
this will filter out all non-Pythagorean triples
triples = list(
filter(lambda triple: triple[2].is_integer(), triples))
print(triples) # prints: [(3, 4, 5.0), (6, 8, 10.0)]
Another way
mx = 10
triples = [(a, b, sqrt(a2 + b2))
for a in range(1, mx) for b in range(a, mx)]
here we combine filter and map in one CLEAN list comprehension
triples = [(a, b, int(c)) for a, b, c in triples if c.is_integer()]
print(triples)
# prints: [(3, 4, 5), (6, 8, 10)]
We can also make _____ comprehensions
dictionary
Dictionaries do not allow _____ keys
duplicate
word = ‘Hello’
swaps = {c: c.swapcase() for c in word}
print(swaps)
prints: {‘H’: ‘h’, ‘e’: ‘E’, ‘l’: ‘L’, ‘o’: ‘O’}
We can also create ____ comprehensions
word = ‘Hello’
letters1 = {c for c in word}
letters2 = set(c for c in word)
print(letters1) # prints: {‘H’, ‘o’, ‘e’, ‘l’}
print(letters1 == letters2) # prints: True
These are very similar to regular functions but instead of returning results through return statements, they use yield which allows them to suspend and resume their state between each call
generator functions
These are very similar to list comprehensions, but instead of returning a list, they return an object that produces results one by one
generator expressions