Dictionary method changes
suggest changeIn Python 3, many of the dictionary methods are quite different in behaviour from Python 2, and many were removed as well: has_key, iter* and view* are gone. Instead of d.has_key(key), which had been long deprecated, one must now use key in d.
In Python 2, dictionary methods keys, values and items return lists. In Python 3 they return view objects instead; the view objects are not iterators, and they differ from them in two ways, namely:
- they have size (one can use the
lenfunction on them) - they can be iterated over many times
Additionally, like with iterators, the changes in the dictionary are reflected in the view objects.
Python 2.7 has backported these methods from Python 3; they’re available as viewkeys, viewvalues and viewitems. To transform Python 2 code to Python 3 code, the corresponding forms are:
d.keys(),d.values()andd.items()of Python 2 should be changed tolist(d.keys()),list(d.values())andlist(d.items())d.iterkeys(),d.itervalues()andd.iteritems()should be changed toiter(d.keys()), or even better,iter(d);iter(d.values())anditer(d.items())respectively- and finally Python 2.7 method calls
d.viewkeys(),d.viewvalues()andd.viewitems()can be replaced withd.keys(),d.values()andd.items().
Porting Python 2 code that iterates over dictionary keys, values or items while mutating it is sometimes tricky. Consider:
d = {'a': 0, 'b': 1, 'c': 2, '!': 3}
for key in d.keys():
if key.isalpha():
del d[key]
The code looks as if it would work similarly in Python 3, but there the keys method returns a view object, not a list, and if the dictionary changes size while being iterated over, the Python 3 code will crash with RuntimeError: dictionary changed size during iteration. The solution is of course to properly write for key in list(d).
Similarly, view objects behave differently from iterators: one cannot use next() on them, and one cannot resume iteration; it would instead restart; if Python 2 code passes the return value of d.iterkeys(), d.itervalues() or d.iteritems() to a method that expects an iterator instead of an iterable, then that should be iter(d), iter(d.values()) or iter(d.items()) in Python 3.