[Python-ideas] Method chaining notation

Chris Angelico rosuav at gmail.com
Wed Feb 26 22:56:32 CET 2014


On Thu, Feb 27, 2014 at 8:17 AM, David Mertz <mertz at gnosis.cx> wrote:
> On Wed, Feb 26, 2014 at 12:54 PM, Ron Adam <ron3200 at gmail.com> wrote:
>>>
>>> For example you could say, we don't need dict.items because we can do...
>>
>>
>>      zip(dict.keys(), dict.values())
>
>
> Have we actually been promised that d.keys() and d.values() walk the
> (unordered) dictionary in the same order, for every Python
> implementation/version?  While I think it is almost certainly true in
> practice, I haven't where this invariant is guaranteed:

Yes, it's promised. It's intrinsic to the definition of keys()/values().

http://docs.python.org/3.4/library/stdtypes.html#dict-views
"""
Keys and values are iterated over in an arbitrary order which is
non-random, varies across Python implementations, and depends on the
dictionary’s history of insertions and deletions. If keys, values and
items views are iterated over with no intervening modifications to the
dictionary, the order of items will directly correspond. This allows
the creation of (value, key) pairs using zip(): pairs =
zip(d.values(), d.keys()). Another way to create the same list is
pairs = [(v, k) for (k, v) in d.items()].
"""

http://docs.python.org/2/library/stdtypes.html#mapping-types-dict
"""
If items(), keys(), values(), iteritems(), iterkeys(), and
itervalues() are called with no intervening modifications to the
dictionary, the lists will directly correspond. This allows the
creation of (value, key) pairs using zip(): pairs =zip(d.values(),
d.keys()). The same relationship holds for the iterkeys() and
itervalues() methods: pairs = zip(d.itervalues(), d.iterkeys())
provides the same value for pairs. Another way to create the same list
is pairs = [(v,k) for (k, v) in d.iteritems()].
"""

The latter has a "CPython implementation detail" box immediately above
the piece I quoted, which in a way emphasizes the fact that the bit
not in the box is not CPython-specific.

Note the criteria, by the way. You have to not modify the dictionary
in any way in between. I believe CPython will maintain iteration order
as long as the set of keys never changes, but it would be legal for a
compliant Python implementation to assert-fail here:

d = {1:2, 3:4, 5:6, 7:8, 9:10}
items = list(d.items())
d[3] = 4 # Breakage
assert items == list(d.items())

However, retrieval is safe. A compliant Python will never assert-fail
if the breakage line is changed to:
spam = d[3] # No breakage

So a splay tree implementation (say) would have to have some other
means of iterating, or it would have to not adjust itself on reads.

ChrisA


More information about the Python-ideas mailing list