Jóan Petur Petersen
List comprehensions:
Traditional code:
old_list = range(4)
new_list = []
for n in old_list:
new_list.append(n**2)
with a list comprehension this can be rewritten as:
old_list = range(4)
new_list = [n**2 for n in old_list]
a simplification of the full syntax:
[expression for variable in iterable]
expression
describes how the elements in the new list are formed.variable
the name of the variable that represent each element in
iterable
.iterable
.The variable
part of the list comprehension does not have to be a single variable.
>>> d = {'kyle': 3, 'stan': 5, 'eric': 0, 'kenny': 7}
>>> d.items()
[('stan', 5), ('kenny', 7), ('kyle', 3), ('eric', 0)]
>>> ["{0} = {1}".format(k, v) for k, v in d.items()]
['stan = 5', 'kenny = 7', 'kyle = 3', 'eric = 0']
an optional filter can be also be added to the list comprehension:
[expression for variable in iterable if condition]
The equivalent code:
new_list = []
for variable in iterable:
if condition:
new_list.append(expression)
>>> d = {'kyle': 3, 'stan': 5, 'eric': 0, 'kenny': 7}
[('stan', 5), ('kenny', 7), ('kyle', 3), ('eric', 0)]
>>> ["%s = %d" % (k, v) for k, v in d.items() if v>0]
['stan = 5', 'kenny = 7', 'kyle = 3']
The filter if
is only for selecting elements - else
can not be used.
An ternary conditional expression
a if test else b
can however be used in the expression
part of the list comprehension.
>>> d = {'kyle': 3, 'stan': 5, 'eric': 0, 'kenny': 7}
[('stan', 5), ('kenny', 7), ('kyle', 3), ('eric', 0)]
>>> ["{0} = 5".format(k) k if (v==0) else "{0} = {1}" % (k, v) \
for k, v in d.items()]
['stan = 5', 'kenny = 7', 'kyle = 3', 'eric = 5']
map(f, x)
is equivalent to [f(xi) for xi in x]
filter(f, x)
is equivalent to [xi for xi in x if f(xi)]
Python versions 2.x the list comprehensions scope leaks into the enclosing scope:
>>> [i for i in range(3)]
[0, 1, 2]
>>> i
2
This is not the case for Python 3.x:
>>> [i for i in range(3)]
[0, 1, 2]
>>> i
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined
Syntax:
(expression for variable in iterable if condition)
>>> [x**2 for x in xrange(4)]
[0, 1, 4, 9]
>>> g = (x**2 for x in xrange(4))
>>> g
<generator object <genexpr> at 0x2ca7d8>
>>> g.next() # In python 3.x use g.__next__()
0
>>> g.next()
1
Note we use xrange(4)
.
There is a special exception where a generator expression does not have to be enclosed in parenthesis
>>> sum(x**2 for x in range(4))
14
Drawbacks:
Dictionary and set comprehensions are also available:
Examples:
>>> {x for x in range(4)}
set([0, 1, 2, 3])
>>> {x:"A"*x for x in range(4)}
{0: '', 1: 'A', 2: 'AA', 3: 'AAA'}
Syntax taken from Python 2.7 reference:
comprehension ::= expression comp_for
comp_for ::= "for" target_list "in" or_test [comp_iter]
comp_iter ::= comp_for | comp_if
comp_if ::= "if" expression_nocond [comp_iter]
A list comprehension of this form:
res = [expression for i1 in L1 if cond1 for i2 in L2 if cond2 ...]
is equivalent to:
res = []
for i1 in L1:
if cond1:
for i2 in L2:
if cond2:
...
res.append(expression)
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
is equivalent to:
>>> combs = []
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
The nested loops can also iterate over variables from the outer loops.
Example:
>>> L = [[1,2,3],[2,3],[1]]
>>> res = []
>>> for vec in L:
... if len(vec)>2:
... for e in vec:
... res.append(e*2)
...
>>> res
[2, 4, 6]
which equivalent to:
>>> L = [[1,2,3],[2,3],[1]]
>>> [e*2 for vec in L if len(vec)>2 for e in vec]
[2, 4, 6]
Nest a list comprehension in the expression.
>>> L = [[1,2,3],[2,3],[1]]
>>> [[i*2 for i in vec] for vec in L if len(vec)>2]
[[2, 4, 6]]
What happend when list comprehensions become long?
PEP8 predates list comprehensions.
[expression
for variable
in iterable
]
Try to avoid two disjoint statements the same line.
PEP 274 Dict Comprehensions http://legacy.python.org/dev/peps/pep-0274/
http://python-history.blogspot.dk/2010/06/from-list-comprehensions-to-generator.html
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |