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:
parent
ee2cc42377
commit
7a5d23bb6b
80
pep-0274.txt
80
pep-0274.txt
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue