PEP: 202 Title: List Comprehensions Version: $Revision$ Owner: tpeters@beopen.com (Tim Peters) Python-Version: 2.0 Status: Incomplete Introduction This PEP describes a proposed syntactical extension to Python, list comprehensions. The Proposed Solution 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. Rationale List comprehensions provide a more concise way to create lists in situations where map() and filter() and/or nested loops would currently be used. 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"] >>> print [(i,f) for i in nums for f in fruit] [(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')] >>> print [(i,f) for i in nums for f in fruit if f[0] == "P"] [(1, 'Peaches'), (1, 'Pears'), (2, 'Peaches'), (2, 'Pears'), (3, 'Peaches'), (3, 'Pears'), (4, 'Peaches'), (4, 'Pears')] >>> print [(i,f) for i in nums for f in fruit if f[0] == "P" if i%2 == 1] [(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')] Reference Implementation Please refer to https://sourceforge.net/patch/?func=detailpatch&patch_id=100654&group_id=5470 for a patch that adds list comprehensions to Python. 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 required to write [(x, y) for ...]. - The form [... for x... for y...] nests, with the last index varying fastest, just like nested for loops. Open Issues Syntax Several people proposed connecting or separating syntax between the various clauses, for example, requiring a semicolon between them to set them apart: [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) It's not clear that this is necessary. The newly proposed zip() builtin takes care of that case. Stability of the Implementation 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. Local Variables: mode: indented-text indent-tabs-mode: nil End: