http://www.secnetix.de/olli/Python/list_comprehensions.hawk
http://www.secnetix.de/olli/Python/list_comprehensions.hawkPython: List Comprehensions
Note: Lines beginning with ">>> "and "... " indicate input to Python (theseare the default prompts of the interactive interpreter).Everything else is output from Python. |
Python supports a concept called "list comprehensions".It can be used to construct lists in a very natural,easy way, like a mathematician is used to do.
The following are common ways to describe lists (orsets, or tuples, or vectors) in mathematics.
S = {x² : x in {0 ... 9}} V = (1, 2, 4, 8, ..., 2¹²) M = {x | x in S and x even} |
You probably know things like the above from mathematicslessons at school. In Python, you can write theseexpression almost exactly like a mathematician woulddo, without having to remember any special crypticsyntax.
This is how you do the above in Python:
>>> S = [x**2 for x in range(10)] >>> V = [2**i for i in range(13)] >>> M = [x for x in S if x % 2 == 0] >>>
>>> print S; print V; print M
|
I'm sure you want to see a more complicated example. :-)The following is yet another way to compute prime numbers.The interesting thing is that we first build a list ofnon-prime numbers, using a single list comprehension,then use another list comprehension to get the "inverse"of the list, which are prime numbers.
>>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)] >>> primes = [x for x in range(2, 50) if x not in noprimes] >>> print primes
|
NB: You can nest list comprehensions inside of each other,so you could write the above example with a singlestatement (without the need for the temporary variable"noprimes
"). However, such lines tend to getlong and less readable, so this is not recommended.
Of course, list comprehensions don't only work for numbers.Lists can contain any type of elements, includingstrings, nested lists and functions. You can evenmix different types within a list.
The following works on a list of strings and produces alist of lists. Each of the sublists contains two stringsand an integer.
>>> words = 'The quick brown fox jumps over the lazy dog'.split() >>> print words
>>>
>>> stuff = [[w.upper(), w.lower(), len(w)] for w in words] >>> for i in stuff: ... print i ...
>>>
>>> stuff = map(lambda w: [w.upper(), w.lower(), len(w)], words) >>> for i in stuff: ... print i ...
|
The above example also demonstrates that you can do exactlythe same thing with map()
and a lambda function.However, there are cases when you cannotuse map()
and have to use a list comprehensioninstead, or vice versa. When you can use both, then itis often preferable to use a list comprehension,because this is more efficient and easier to read,most of the time.
You cannot use list comprehensions when the constructionrule is too complicated to be expressed with "for" and "if"statements, or if the construction rule can change dynamicallyat runtime. In this case, you betteruse map()
and / or filter()
with anappropriate function.Of course, you can combine that with list comprehensions.