2001-10-25 16:28:05 -04:00
|
|
|
PEP: 274
|
|
|
|
Title: Dict Comprehensions
|
|
|
|
Version: $Revision$
|
|
|
|
Last-Modified: $Date$
|
2012-04-09 10:42:15 -04:00
|
|
|
Author: Barry Warsaw <barry@python.org>
|
2012-05-01 07:47:47 -04:00
|
|
|
Status: Final
|
2001-10-25 16:28:05 -04:00
|
|
|
Type: Standards Track
|
2017-01-10 14:30:39 -05:00
|
|
|
Content-Type: text/x-rst
|
2001-10-25 16:28:05 -04:00
|
|
|
Created: 25-Oct-2001
|
2022-04-20 05:53:08 -04:00
|
|
|
Python-Version: 2.7, 3.0
|
2001-10-29 13:46:59 -05:00
|
|
|
Post-History: 29-Oct-2001
|
2001-10-25 16:28:05 -04:00
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
2017-01-10 14:30:39 -05:00
|
|
|
========
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2022-01-21 06:03:51 -05:00
|
|
|
:pep:`202` introduces a syntactical extension to Python called the
|
2017-01-10 14:30:39 -05:00
|
|
|
"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.
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2012-04-09 10:42:15 -04:00
|
|
|
|
2005-06-16 22:13:11 -04:00
|
|
|
Resolution
|
2017-01-10 14:30:39 -05:00
|
|
|
==========
|
2005-06-16 22:13:11 -04:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
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.
|
2005-06-16 22:13:11 -04:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
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.
|
2008-12-02 19:55:07 -05:00
|
|
|
|
2001-10-25 16:28:05 -04:00
|
|
|
|
|
|
|
Proposed Solution
|
2017-01-10 14:30:39 -05:00
|
|
|
=================
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
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.
|
2001-10-25 16:28:05 -04:00
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
2017-01-10 14:30:39 -05:00
|
|
|
=========
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
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.
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
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.
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
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.
|
2001-10-25 16:28:05 -04:00
|
|
|
|
|
|
|
|
2001-10-31 10:09:55 -05:00
|
|
|
Semantics
|
2017-01-10 14:30:39 -05:00
|
|
|
=========
|
2001-10-31 10:09:55 -05:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
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::
|
2001-10-31 10:09:55 -05:00
|
|
|
|
2001-10-31 10:50:36 -05:00
|
|
|
>>> dict([(i, chr(65+i)) for i in range(4)])
|
2001-10-31 10:09:55 -05:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
is semantically equivalent to::
|
2001-10-31 10:09:55 -05:00
|
|
|
|
|
|
|
>>> {i : chr(65+i) for i in range(4)}
|
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
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.
|
2001-10-31 10:09:55 -05:00
|
|
|
|
|
|
|
|
2001-10-25 16:28:05 -04:00
|
|
|
Examples
|
2017-01-10 14:30:39 -05:00
|
|
|
========
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-04-05 12:14:26 -04:00
|
|
|
::
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-04-05 12:14:26 -04:00
|
|
|
>>> print {i : chr(65+i) for i in range(4)}
|
|
|
|
{0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-04-05 12:14:26 -04:00
|
|
|
::
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-04-05 12:14:26 -04:00
|
|
|
>>> print {k : v for k, v in someDict.iteritems()} == someDict.copy()
|
|
|
|
1
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-04-05 12:14:26 -04:00
|
|
|
::
|
2001-10-31 10:09:55 -05:00
|
|
|
|
2017-04-05 12:14:26 -04:00
|
|
|
>>> print {x.lower() : 1 for x in list_of_email_addrs}
|
|
|
|
{'barry@zope.com' : 1, 'barry@python.org' : 1, 'guido@python.org' : 1}
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-04-05 12:14:26 -04:00
|
|
|
::
|
2001-10-29 13:46:59 -05:00
|
|
|
|
2017-04-05 12:14:26 -04:00
|
|
|
>>> 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}
|
2001-10-25 16:28:05 -04:00
|
|
|
|
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
Implementation
|
|
|
|
==============
|
2001-10-25 16:28:05 -04:00
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
All implementation details were resolved in the Python 2.7 and 3.0
|
|
|
|
time-frame.
|
2001-10-25 16:28:05 -04:00
|
|
|
|
|
|
|
|
|
|
|
Copyright
|
2017-01-10 14:30:39 -05:00
|
|
|
=========
|
|
|
|
|
|
|
|
This document has been placed in the public domain.
|
2001-10-25 16:28:05 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
2017-01-10 14:30:39 -05:00
|
|
|
..
|
|
|
|
Local Variables:
|
|
|
|
mode: indented-text
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
fill-column: 70
|
|
|
|
End:
|