python 3 dict: .keys(), .values(), and .item()

Peter Otten __peter__ at
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 

> 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


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 

More information about the Python-list mailing list