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:
