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. -- https://mail.python.org/mailman/listinfo/python-list