@@ -163,107 +163,137 @@ have fast appends and pops from both ends. For example::
163163List Comprehensions
164164-------------------
165165
166- List comprehensions provide a concise way to create lists from sequences .
167- Common applications are to make lists where each element is the result of
168- some operations applied to each member of the sequence, or to create a
169- subsequence of those elements that satisfy a certain condition.
166+ List comprehensions provide a concise way to create lists.
167+ Common applications are to make new lists where each element is the result of
168+ some operations applied to each member of another sequence or iterable, or to
169+ create a subsequence of those elements that satisfy a certain condition.
170170
171- A list comprehension consists of brackets containing an expression followed
172- by a :keyword: `for ` clause, then zero or more :keyword: `for ` or :keyword: `if `
173- clauses. The result will be a list resulting from evaluating the expression in
174- the context of the :keyword: `for ` and :keyword: `if ` clauses which follow it. If
175- the expression would evaluate to a tuple, it must be parenthesized.
171+ For example, assume we want to create a list of squares, like::
172+
173+ >>> squares = []
174+ >>> for x in range(10):
175+ ... squares.append(x**2)
176+ ...
177+ >>> squares
178+ [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
179+
180+ We can obtain the same result with::
176181
177- Here we take a list of numbers and return a list of three times each number::
182+ squares = [x**2 for x in range(10)]
178183
179- >>> vec = [2, 4, 6]
180- >>> [3*x for x in vec]
181- [6, 12, 18]
184+ This is also equivalent to ``squares = map(lambda x: x**2, range(10)) ``,
185+ but it's more concise and readable.
182186
183- Now we get a little fancier::
187+ A list comprehension consists of brackets containing an expression followed
188+ by a :keyword: `for ` clause, then zero or more :keyword: `for ` or :keyword: `if `
189+ clauses. The result will be a new list resulting from evaluating the expression
190+ in the context of the :keyword: `for ` and :keyword: `if ` clauses which follow it.
191+ For example, this listcomp combines the elements of two lists if they are not
192+ equal::
184193
185- >>> [[ x, x**2 ] for x in vec ]
186- [[2, 4], [4, 16], [6, 36] ]
194+ >>> [( x, y) for x in [1,2,3 ] for y in [3,1,4] if x != y ]
195+ [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4) ]
187196
188- Here we apply a method call to each item in a sequence ::
197+ and it's equivalent to ::
189198
199+ >>> combs = []
200+ >>> for x in [1,2,3]:
201+ ... for y in [3,1,4]:
202+ ... if x != y:
203+ ... combs.append((x, y))
204+ ...
205+ >>> combs
206+ [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
207+
208+ Note how the order of the :keyword: `for ` and :keyword: `if ` statements is the
209+ same in both these snippets.
210+
211+ If the expression is a tuple (e.g. the ``(x, y) `` in the previous example),
212+ it must be parenthesized. ::
213+
214+ >>> vec = [-4, -2, 0, 2, 4]
215+ >>> # create a new list with the values doubled
216+ >>> [x*2 for x in vec]
217+ [-8, -4, 0, 4, 8]
218+ >>> # filter the list to exclude negative numbers
219+ >>> [x for x in vec if x >= 0]
220+ [0, 2, 4]
221+ >>> # apply a function to all the elements
222+ >>> [abs(x) for x in vec]
223+ [4, 2, 0, 2, 4]
224+ >>> # call a method on each element
190225 >>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
191226 >>> [weapon.strip() for weapon in freshfruit]
192227 ['banana', 'loganberry', 'passion fruit']
193-
194- Using the :keyword: `if ` clause we can filter the stream::
195-
196- >>> [3*x for x in vec if x > 3]
197- [12, 18]
198- >>> [3*x for x in vec if x < 2]
199- []
200-
201- Tuples can often be created without their parentheses, but not here::
202-
203- >>> [x, x**2 for x in vec] # error - parens required for tuples
228+ >>> # create a list of 2-tuples like (number, square)
229+ >>> [(x, x**2) for x in range(6)]
230+ [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
231+ >>> # the tuple must be parenthesized, otherwise an error is raised
232+ >>> [x, x**2 for x in range(6)]
204233 File "<stdin>", line 1, in ?
205- [x, x**2 for x in vec ]
234+ [x, x**2 for x in range(6) ]
206235 ^
207236 SyntaxError: invalid syntax
208- >>> [(x, x**2) for x in vec]
209- [(2, 4), (4, 16), (6, 36)]
210-
211- Here are some nested for loops and other fancy behavior::
212-
213- >>> vec1 = [2, 4, 6]
214- >>> vec2 = [4, 3, -9]
215- >>> [x*y for x in vec1 for y in vec2]
216- [8, 6, -18, 16, 12, -36, 24, 18, -54]
217- >>> [x+y for x in vec1 for y in vec2]
218- [6, 5, -7, 8, 7, -5, 10, 9, -3]
219- >>> [vec1[i]*vec2[i] for i in range(len(vec1))]
220- [8, 12, -54]
237+ >>> # flatten a list using a listcomp with two 'for'
238+ >>> vec = [[1,2,3], [4,5,6], [7,8,9]]
239+ >>> [num for elem in vec for num in elem]
240+ [1, 2, 3, 4, 5, 6, 7, 8, 9]
221241
222- List comprehensions can be applied to complex expressions and nested functions::
242+ List comprehensions can contain complex expressions and nested functions::
223243
224- >>> [str(round(355/113, i)) for i in range(1, 6)]
244+ >>> from math import pi
245+ >>> [str(round(pi, i)) for i in range(1, 6)]
225246 ['3.1', '3.14', '3.142', '3.1416', '3.14159']
226247
227-
228248Nested List Comprehensions
229249--------------------------
230250
231- If you've got the stomach for it, list comprehensions can be nested. They are a
232- powerful tool but -- like all powerful tools -- they need to be used carefully,
233- if at all.
234-
235- Consider the following example of a 3x3 matrix held as a list containing three
236- lists, one list per row::
237-
238- >>> mat = [
239- ... [1, 2, 3],
240- ... [4, 5, 6],
241- ... [7, 8, 9],
242- ... ]
251+ The initial expression in a list comprehension can be any arbitrary expression,
252+ including another list comprehension.
243253
244- Now, if you wanted to swap rows and columns, you could use a list
245- comprehension ::
254+ Consider the following example of a 3x4 matrix implemented as a list of
255+ 3 lists of length 4 ::
246256
247- >>> print([[row[i] for row in mat] for i in [0, 1, 2]])
248- [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
257+ >>> matrix = [
258+ ... [1, 2, 3, 4],
259+ ... [5, 6, 7, 8],
260+ ... [9, 10, 11, 12],
261+ ... ]
249262
250- Special care has to be taken for the * nested * list comprehension :
263+ The following list comprehension will transpose rows and columns: :
251264
252- To avoid apprehension when nesting list comprehensions, read from right to
253- left.
265+ >>> [[row[i] for row in matrix] for i in range(4)]
266+ [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
254267
255- A more verbose version of this snippet shows the flow explicitly::
268+ As we saw in the previous section, the nested listcomp is evaluated in
269+ the context of the :keyword: `for ` that follows it, so this example is
270+ equivalent to::
256271
257- for i in [0, 1, 2]:
258- for row in mat:
259- print(row[i], end="")
260- print()
272+ >>> transposed = []
273+ >>> for i in range(4):
274+ ... transposed.append([row[i] for row in matrix])
275+ ...
276+ >>> transposed
277+ [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
278+
279+ which, in turn, is the same as::
280+
281+ >>> transposed = []
282+ >>> for i in range(4):
283+ ... # the following 3 lines implement the nested listcomp
284+ ... transposed_row = []
285+ ... for row in matrix:
286+ ... transposed_row.append(row[i])
287+ ... transposed.append(transposed_row)
288+ ...
289+ >>> transposed
290+ [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
261291
262- In real world, you should prefer built-in functions to complex flow statements.
292+ In the real world, you should prefer built-in functions to complex flow statements.
263293The :func: `zip ` function would do a great job for this use case::
264294
265- >>> list( zip(*mat) )
266- [(1, 4, 7 ), (2, 5, 8 ), (3, 6, 9 )]
295+ >>> zip(*matrix )
296+ [(1, 5, 9 ), (2, 6, 10 ), (3, 7, 11), (4, 8, 12 )]
267297
268298See :ref: `tut-unpacking-arguments ` for details on the asterisk in this line.
269299
0 commit comments