Permalink
Cannot retrieve contributors at this time
149 lines (106 sloc)
4.11 KB
| PEP: 274 | |
| Title: Dict Comprehensions | |
| Version: $Revision$ | |
| Last-Modified: $Date$ | |
| Author: Barry Warsaw <barry@python.org> | |
| Status: Final | |
| Type: Standards Track | |
| Content-Type: text/x-rst | |
| Created: 25-Oct-2001 | |
| Python-Version: 2.7, 3.0 (originally 2.3) | |
| Post-History: 29-Oct-2001 | |
| Abstract | |
| ======== | |
| PEP 202 introduces a syntactical extension to Python called the | |
| "list comprehension". This PEP proposes a similar syntactical | |
| extension called the "dictionary comprehension" or "dict | |
| comprehension" for short. You can use dict comprehensions in ways | |
| very similar to list comprehensions, except that they produce | |
| Python dictionary objects instead of list objects. | |
| Resolution | |
| ========== | |
| This PEP was originally written for inclusion in Python 2.3. It | |
| was withdrawn after observation that substantially all of its | |
| benefits were subsumed by generator expressions coupled with the | |
| ``dict()`` constructor. | |
| However, Python 2.7 and 3.0 introduces this exact feature, as well | |
| as the closely related set comprehensions. On 2012-04-09, the PEP | |
| was changed to reflect this reality by updating its Status to | |
| Accepted, and updating the Python-Version field. The Open | |
| Questions section was also removed since these have been long | |
| resolved by the current implementation. | |
| Proposed Solution | |
| ================= | |
| Dict comprehensions are just like list comprehensions, except that | |
| you group the expression using curly braces instead of square | |
| braces. Also, the left part before the ``for`` keyword expresses | |
| both a key and a value, separated by a colon. The notation is | |
| specifically designed to remind you of list comprehensions as | |
| applied to dictionaries. | |
| Rationale | |
| ========= | |
| There are times when you have some data arranged as a sequences of | |
| length-2 sequences, and you want to turn that into a dictionary. | |
| In Python 2.2, the ``dict()`` constructor accepts an argument that is | |
| a sequence of length-2 sequences, used as (key, value) pairs to | |
| initialize a new dictionary object. | |
| However, the act of turning some data into a sequence of length-2 | |
| sequences can be inconvenient or inefficient from a memory or | |
| performance standpoint. Also, for some common operations, such as | |
| turning a list of things into a set of things for quick duplicate | |
| removal or set inclusion tests, a better syntax can help code | |
| clarity. | |
| As with list comprehensions, an explicit for loop can always be | |
| used (and in fact was the only way to do it in earlier versions of | |
| Python). But as with list comprehensions, dict comprehensions can | |
| provide a more syntactically succinct idiom that the traditional | |
| for loop. | |
| Semantics | |
| ========= | |
| The semantics of dict comprehensions can actually be demonstrated | |
| in stock Python 2.2, by passing a list comprehension to the | |
| built-in dictionary constructor:: | |
| >>> dict([(i, chr(65+i)) for i in range(4)]) | |
| is semantically equivalent to:: | |
| >>> {i : chr(65+i) for i in range(4)} | |
| The dictionary constructor approach has two distinct disadvantages | |
| from the proposed syntax though. First, it isn't as legible as a | |
| dict comprehension. Second, it forces the programmer to create an | |
| in-core list object first, which could be expensive. | |
| Examples | |
| ======== | |
| :: | |
| >>> print {i : chr(65+i) for i in range(4)} | |
| {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'} | |
| :: | |
| >>> print {k : v for k, v in someDict.iteritems()} == someDict.copy() | |
| 1 | |
| :: | |
| >>> print {x.lower() : 1 for x in list_of_email_addrs} | |
| {'barry@zope.com' : 1, 'barry@python.org' : 1, 'guido@python.org' : 1} | |
| :: | |
| >>> def invert(d): | |
| ... return {v : k for k, v in d.iteritems()} | |
| ... | |
| >>> d = {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'} | |
| >>> print invert(d) | |
| {'A' : 0, 'B' : 1, 'C' : 2, 'D' : 3} | |
| :: | |
| >>> {(k, v): k+v for k in range(4) for v in range(4)} | |
| ... {(3, 3): 6, (3, 2): 5, (3, 1): 4, (0, 1): 1, (2, 1): 3, | |
| (0, 2): 2, (3, 0): 3, (0, 3): 3, (1, 1): 2, (1, 0): 1, | |
| (0, 0): 0, (1, 2): 3, (2, 0): 2, (1, 3): 4, (2, 2): 4, ( | |
| 2, 3): 5} | |
| Implementation | |
| ============== | |
| All implementation details were resolved in the Python 2.7 and 3.0 | |
| time-frame. | |
| Copyright | |
| ========= | |
| This document has been placed in the public domain. | |
| .. | |
| Local Variables: | |
| mode: indented-text | |
| indent-tabs-mode: nil | |
| fill-column: 70 | |
| End: |