From 7a5d23bb6bddc386215c7855b6fb1fcb096f3ef0 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Mon, 29 Oct 2001 18:46:59 +0000 Subject: [PATCH] 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. --- pep-0274.txt | 80 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/pep-0274.txt b/pep-0274.txt index 22827057c..d2faae601 100644 --- a/pep-0274.txt +++ b/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