2000-07-13 02:33:08 -04:00
|
|
|
PEP: 202
|
|
|
|
Title: List Comprehensions
|
|
|
|
Version: $Revision$
|
2000-10-30 15:48:44 -05:00
|
|
|
Author: tim@digicool.com (Tim Peters)
|
2000-08-23 01:19:21 -04:00
|
|
|
Status: Draft
|
|
|
|
Type: Standards Track
|
2000-07-13 02:33:08 -04:00
|
|
|
Python-Version: 2.0
|
2000-08-23 01:19:21 -04:00
|
|
|
Created: 13-Jul-2000
|
|
|
|
Post-History:
|
2000-07-13 02:33:08 -04:00
|
|
|
|
2000-07-27 16:13:39 -04:00
|
|
|
|
2000-07-25 11:07:28 -04:00
|
|
|
Introduction
|
|
|
|
|
2000-08-23 01:19:21 -04:00
|
|
|
This PEP describes a proposed syntactical extension to Python,
|
|
|
|
list comprehensions.
|
2000-07-25 11:07:28 -04:00
|
|
|
|
2000-07-27 16:13:39 -04:00
|
|
|
|
2000-07-25 11:07:28 -04:00
|
|
|
The Proposed Solution
|
|
|
|
|
2000-08-23 01:19:21 -04:00
|
|
|
It is proposed to allow conditional construction of list literals
|
|
|
|
using for and if clauses. They would nest in the same way for
|
|
|
|
loops and if statements nest now.
|
2000-07-25 11:07:28 -04:00
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
|
|
|
List comprehensions provide a more concise way to create lists in
|
2000-08-23 01:19:21 -04:00
|
|
|
situations where map() and filter() and/or nested loops would
|
|
|
|
currently be used.
|
2000-07-25 11:07:28 -04:00
|
|
|
|
2000-07-27 16:13:39 -04:00
|
|
|
|
2000-07-25 11:07:28 -04:00
|
|
|
Examples
|
|
|
|
|
|
|
|
>>> print [i for i in range(10)]
|
|
|
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
|
|
|
|
|
|
>>> print [i for i in range(20) if i%2 == 0]
|
|
|
|
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
|
|
|
|
|
|
|
|
>>> nums = [1,2,3,4]
|
|
|
|
>>> fruit = ["Apples", "Peaches", "Pears", "Bananas"]
|
2000-07-27 16:13:39 -04:00
|
|
|
>>> print [(i,f) for i in nums for f in fruit]
|
2000-07-25 11:07:28 -04:00
|
|
|
[(1, 'Apples'), (1, 'Peaches'), (1, 'Pears'), (1, 'Bananas'),
|
|
|
|
(2, 'Apples'), (2, 'Peaches'), (2, 'Pears'), (2, 'Bananas'),
|
|
|
|
(3, 'Apples'), (3, 'Peaches'), (3, 'Pears'), (3, 'Bananas'),
|
|
|
|
(4, 'Apples'), (4, 'Peaches'), (4, 'Pears'), (4, 'Bananas')]
|
2000-07-27 16:13:39 -04:00
|
|
|
>>> print [(i,f) for i in nums for f in fruit if f[0] == "P"]
|
2000-07-25 11:07:28 -04:00
|
|
|
[(1, 'Peaches'), (1, 'Pears'),
|
|
|
|
(2, 'Peaches'), (2, 'Pears'),
|
|
|
|
(3, 'Peaches'), (3, 'Pears'),
|
|
|
|
(4, 'Peaches'), (4, 'Pears')]
|
2000-07-27 16:13:39 -04:00
|
|
|
>>> print [(i,f) for i in nums for f in fruit if f[0] == "P" if i%2 == 1]
|
2000-07-25 11:07:28 -04:00
|
|
|
[(1, 'Peaches'), (1, 'Pears'), (3, 'Peaches'), (3, 'Pears')]
|
|
|
|
>>> def zip(*args):
|
|
|
|
... return apply(map, (None,)+args)
|
|
|
|
...
|
|
|
|
>>> print [i for i in zip(nums,fruit) if i[0]%2==0]
|
|
|
|
[(2, 'Peaches'), (4, 'Bananas')]
|
|
|
|
|
2000-07-27 16:13:39 -04:00
|
|
|
|
2000-07-25 11:07:28 -04:00
|
|
|
Reference Implementation
|
|
|
|
|
2000-08-23 01:19:21 -04:00
|
|
|
SourceForge contains a patch that adds list comprehensions to Python[1].
|
2000-07-25 11:07:28 -04:00
|
|
|
|
|
|
|
|
2000-07-27 16:13:39 -04:00
|
|
|
BDFL Pronouncements
|
|
|
|
|
|
|
|
Note: the BDFL refers to Guido van Rossum, Python's Benevolent
|
|
|
|
Dictator For Life.
|
|
|
|
|
|
|
|
- The syntax proposed above is the Right One.
|
|
|
|
|
|
|
|
- The form [x, y for ...] should be disallowed; one should be
|
2000-08-23 01:19:21 -04:00
|
|
|
required to write [(x, y) for ...].
|
2000-07-27 16:13:39 -04:00
|
|
|
|
|
|
|
- The form [... for x... for y...] nests, with the last index
|
2000-08-23 01:19:21 -04:00
|
|
|
varying fastest, just like nested for loops.
|
2000-07-27 16:13:39 -04:00
|
|
|
|
|
|
|
|
2000-07-25 11:07:28 -04:00
|
|
|
Open Issues
|
|
|
|
|
|
|
|
Syntax
|
|
|
|
|
2000-08-23 01:19:21 -04:00
|
|
|
Several people proposed connecting or separating syntax
|
|
|
|
between the various clauses, for example, requiring a
|
|
|
|
semicolon between them to set them apart:
|
2000-07-25 11:07:28 -04:00
|
|
|
|
|
|
|
[i,f; for i in nums; for f in fruit; if f[0]=="P"; if i%2==1]
|
|
|
|
|
|
|
|
To minimize strain on the Python parser, Guido has suggested
|
|
|
|
requiring parentheses around the initial tuple:
|
|
|
|
|
|
|
|
[(i,f) for i in nums for f in fruit if f[0]=="P" if i%2==1]
|
|
|
|
|
|
|
|
Semantics
|
|
|
|
|
|
|
|
The semantics of multiple for clauses is not obvious to many
|
|
|
|
people. Currently, it nests, so that
|
|
|
|
|
|
|
|
[i,f for i in nums for f in fruit]
|
|
|
|
|
|
|
|
is functionally equivalent to
|
|
|
|
|
|
|
|
tmp = []
|
|
|
|
for i in nums:
|
|
|
|
for f in fruit:
|
|
|
|
tmp.append((i,f))
|
|
|
|
|
|
|
|
Other people would read it as if it executed
|
|
|
|
|
|
|
|
map(None, nums, fruit)
|
|
|
|
|
2000-08-23 01:19:21 -04:00
|
|
|
It's not clear that this is necessary. The newly proposed
|
|
|
|
zip() builtin[2] takes care of that case.
|
2000-07-25 11:07:28 -04:00
|
|
|
|
|
|
|
Stability of the Implementation
|
|
|
|
|
2000-08-23 01:19:21 -04:00
|
|
|
The current reference implementation is simply an adaptation
|
|
|
|
of Greg Ewing's original demonstration of the concept. Other
|
|
|
|
than tracking changes to the source code to keep it a valid
|
|
|
|
patch, reindenting the code and switching to function
|
|
|
|
prototypes, nothing has been done to it. This obviously
|
|
|
|
raises some questions about how stable the code is. It has
|
|
|
|
not had a lot of exercise, though the patch does include a few
|
|
|
|
test cases.
|
|
|
|
|
|
|
|
|
|
|
|
References
|
|
|
|
|
|
|
|
[1] https://sourceforge.net/patch/?func=detailpatch&patch_id=100654&group_id=5470
|
|
|
|
[2] Lockstep Iteration, pep-0201.txt
|
2000-07-25 11:07:28 -04:00
|
|
|
|
2000-07-27 16:13:39 -04:00
|
|
|
|
2000-07-13 02:33:08 -04:00
|
|
|
Local Variables:
|
|
|
|
mode: indented-text
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
End:
|