python 3 dict: .keys(), .values(), and .item()
Peter Otten
__peter__ at web.de
Sat Jan 7 18:04:26 EST 2017
Ethan Furman wrote:
> In Python 2 we have:
>
> dict().keys() \
> dict().items() --> separate list() of the results
> dict().values() /
>
> and
>
> dict().iter_keys() \
> dict().iter_items() --> integrated iter() of the results
> dict().iter_values() /
I guess you didn't use these as often as I did ;)
By the way, there are also the virtually unused/unknown dict.viewXXX()
methods that are the exact? equivalent to the dict.XXX() methods in Python
3.
> By "separate list" I mean a snapshot of the dict at the time, and by
> "integrated iter()" I mean changes to the dict during iteration are
> seen by the iter.
>
> In Python 3 the iter_* methods replaced the list() type methods, which
> makes sense from the point-of-view of moving to a more iterator based
> language; however, as a result of that change the typical "iterate over
> a dict" operation now has a built-in gotcha: modifying the dict during
> the iteration can now cause exceptions.
>
> The solution, of course, is simple: surround the iterator call with
> list():
>
> list(dict.keys())
> list(dict.items())
> list(dict.values())
>
> for k, v in list(flag._value2member_map_.items()):
> ...
>
> The solution, however, feels a lot more boilerplate-ish. Either the
> programmer takes a lot more care to remember the current state of the dict
> (since it's no longer a snapshot), or "list()" is sprinkled around every
> iterator access.
>
> In other words, what used to be a completely safe operation now is not.
>
> Thoughts?
Is code that was written for Python 3 riddled with list(...) calls?
That's not my impression.
Do you see
RuntimeError: dictionary changed size during iteration
regularly?
I don't, and while I wouldn't have changed the dict interface I think Python
3's items() and values() -- who uses keys()? -- are clearly the better
defaults.
More information about the Python-list
mailing list