Python 3: dict & dict.keys()

Steven D'Aprano steve+comp.lang.python at
Thu Jul 25 09:04:38 CEST 2013

On Wed, 24 Jul 2013 11:31:58 -0700, Ethan Furman wrote:

> On 07/24/2013 10:23 AM, Stefan Behnel wrote:
>> Peter Otten, 24.07.2013 08:23:
>>> Ethan Furman wrote:
>>>> So, my question boils down to:  in Python 3 how is dict.keys()
>>>> different from dict?  What are the use cases?
>>> To me it looks like views are a solution waiting for a problem.
>> They reduce the API overhead. Previously, you needed values() and
>> itervalues(), with values() being not more than a special case of what
>> itervalues() provides anyway. Now it's just one method that gives you
>> everything. It simply has corrected the tradeoff from two special
>> purpose APIs to one general purpose API, that's all.
> I started this thread for two reasons:
>    1) Increase awareness that using `list(dict)` is a cross-version
>    replacement for `dict.keys()`
>    2) Hopefully learn something about when a view is useful.
> So far #2 is pretty much a failure.

I don't think so.

- viewkeys() can be used as a drop-in replacement for iterkeys(), 
provided you remember not to iterate over it a second time. Doing so 
actually iterates over the view, instead of failing as with the iterator. 
If you actually want a one-shot iterator, call iter() on the view.

- viewkeys() can be used as a drop-in replacement for Python2 keys(), 
provided you only iterate over it once. If you want an actual list, call 
list() on the view.

- Views support set methods which don't modify the set. If there is a non-
modifying set method which is not supported, it probably should be, and 
somebody should raise an enhancement request in the bug tracker. If you 
want an actual independent set you can modify without changing the dict, 
call set() (or frozenset) on the view.

- Views support efficient (O(1) in the case of keys) membership testing, 
which neither iterkeys() nor Python2 keys() does.

- Views support live, read-only access to dict keys and values.

> Only one use-case so far (and it
> feels pretty rare).

Iterating over a dict's values or items is not rare. Using a view is 
better than making a list-copy of the dict and iterating over the list, 
because it avoids copying.

For one-shot iteration, there's no benefit of a view over an iterator, or 
vice versa, but views are useful for more than just one-shot iteration.

> But hey, I have learned that while some set
> operations are allowed (&, ^, |, .isdisjoint()), others are not
> (.remove(), .discard(), .union(), etc.).
> The old .keys(), .values(), and .items() (and their .iter...()
> variations) did something commonly useful.  Of what common use are these
> views?

Everything that dict iteration does, dict views do, and more. So if 
iterkeys() is useful, then so is viewkeys(). Had viewkeys come first, 
iterkeys would never have been invented.

Making an actual list copy of the keys (values, items) is useful, but 
it's not useful enough to dedicate a method (three methods) for it. Just 
call list() on the view (or, in the case of keys, directly on the dict).


More information about the Python-list mailing list