Updates and fixes based on community comments. Some of the examples

has bugs in them.  Also, they should use Python 2.2's {}.iteritems()
where appropriate.

Renamed and reorg'd the Open Issues section, with an entry about the
shortcut syntax, and a question about nested for loop.

Added a section on Implementation, noting Python 2.2's new dictionary
sequence-of-2-element-sequences constructor.
This commit is contained in:
Barry Warsaw 2001-10-29 18:46:59 +00:00
parent ee2cc42377
commit 7a5d23bb6b
1 changed files with 56 additions and 24 deletions

View File

@ -7,7 +7,7 @@ Status: Draft
Type: Standards Track
Created: 25-Oct-2001
Python-Version: 2.3
Post-History:
Post-History: 29-Oct-2001
Abstract
@ -59,44 +59,76 @@ 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.items()} == someDict.copy()
>>> 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}
... 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' : 4}
>>> print {k, v for k in range(4) for v in range(-4, 0, 1)}
{0 : -4, 1 : -3, 2 : -2, 3 : -1}
{'A' : 0, 'B' : 1, 'C' : 2, 'D' : 3}
Optional Enhancements
Open Issues
There is one further shortcut we could adopt. Suppose we wanted
to create a set of items, such as in the "list_of_email_addrs"
example above. Here, we're simply taking the target of the for
loop and turning that into the key for the dict comprehension.
The assertion is that this would be a common idiom, so the
shortcut below allows for an easy spelling of it, by allow us to
omit the "key :" part of the left hand clause:
- There is one further shortcut we could adopt. Suppose we wanted
to create a set of items, such as in the "list_of_email_addrs"
example above. Here, we're simply taking the target of the for
loop and turning that into the key for the dict comprehension.
The assertion is that this would be a common idiom, so the
shortcut below allows for an easy spelling of it, by allow us to
omit the "key :" part of the left hand clause:
>>> print {1 for x in list_of_email_addrs}
{'barry@zope.com' : 1, 'barry@python.org' : 1, 'guido@python.org' : 1}
>>> print {1 for x in list_of_email_addrs}
{'barry@zope.com' : 1, 'barry@python.org' : 1, 'guido@python.org' : 1}
Or say we wanted to map email addresses to the MX record handling
their mail:
Or say we wanted to map email addresses to the MX record handling
their mail:
>>> print {mx_for_addr(x) for x in list_of_email_addrs}
{'barry@zope.com' : 'mail.zope.com',
'barry@python.org' : 'mail.python.org,
'guido@python.org' : 'mail.python.org,
}
>>> print {mx_for_addr(x) for x in list_of_email_addrs}
{'barry@zope.com' : 'mail.zope.com',
'barry@python.org' : 'mail.python.org,
'guido@python.org' : 'mail.python.org,
}
Questions: what about nested loops? Where does the key come
from? The shortcut probably doesn't save much typing, and comes
at the expense of legibility, so it's of dubious value.
- Should nested for loops be allowed? The following example,
taken from an earlier revision of this PEP illustrates the
problem:
>>> print {k, v for k in range(4) for v in range(-4, 0, 1)}
The intent of this example was to produce a mapping from a
number to its negative, but this code doesn't work because -- as
in list comprehensions -- the for loops are nested, not in
parallel! So the value of this expression is actually
{0: -1, 1: -1, 2: -1, 3: -1}
which seems of dubious value. For symmetry with list
comprehensions, perhaps this should be allowed, but it might be
better to disallow this syntax.
Implementation
The semantics of dictionary comprehensions can actually be modeled
in stock Python 2.2, by passing a list comprehension to the
builtin dictionary constructor:
>>> dictionary([(i, chr(65+i)) for i in range(4)])
This has two dictinct disadvantages from the proposed syntax
though. First, it's 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.
References