1

After reading What are Python dictionary view objects? and … what are the performance tradeoffs …? and the official documentation about views on Python dictionaries, I still lack a decent usecase which makes me understand why they are there.

The idea is to have a view on the dictionary which has two major differences to creating a list of the keys/values/items: ① It's faster created (in constant time) and with constant amount of memory footprint and ② it reflects changes in the dictionary also after its creation.

This is fine and understood but I lack an idea when it would be useful to have this. After all wherever I pass such a view, I could pass the dictionary itself instead. It will also be passed in constant time without additional memory footprint and it will also reflect changes on itself (of course). Whatever I would want to do with the view I could also do with the passed dictionary itself. Or am I missing something?

Someone mentioned that using iteritems() (iter() in Python3) on a dictionary while it was changing would invalidate the iterator. This is true. Unfortunately this is likewise true for any iterator created to iterate over a view. So again there is no difference.

So what's the benefit of using a view? Is there any practical usecase which goes beyond what can be found in the older questions linked above?

Alfe
  • 56,346
  • 20
  • 107
  • 159
  • It seems that if points (1) and (2) don't convince you of the value of dictionary views then this is mostly going to be a discussion of opinions. – larsks Sep 18 '17 at 11:50
  • @larsks There is no concrete usecase in the linked Q/A threads. It is a mere description what is possible with them. I'm asking for a usecase. Some situation in which I'm happy to have these because without these I would have a problem without a simple solution. – Alfe Sep 18 '17 at 12:22
  • @larsks The situation here is a bit like an additional plus operator for integers (let's say a method called `add()` besides the one called `__add__()`). One can document how to use it and what it will result in etc. but without a usecase which explains what's their benefit over the alternatives, their existence remains questionable. So if you understand in which situation they are to be used because the alternatives are less optimal, I'd be happy to get an answer to my question from you. – Alfe Sep 18 '17 at 12:26
  • 1
    Views also act as *sets*; anything where a set operations can help is a potentional usecase. As [stated in the PEP](https://www.python.org/dev/peps/pep-3106/#open-issues): *Do we need more of a motivation? I would think that being able to do set operations on keys and items without having to copy them should speak for itself.* – Martijn Pieters Sep 21 '17 at 10:16
  • I made some timing measurements (see in a comment below) which show that using `set(d)` works well for creating a set of the keys, especially faster than using `d.viewkeys()` instead. A single usecase would be enough to answer the question, so it surely isn't "too broad". Not everything one hasn't an answer for should be put on hold. Sometimes it also points out a particularly difficult to answer aspect. By closing the Q an answer isn't possible, though. +3/-2 also shows how controversial the question is. – Alfe Sep 21 '17 at 15:04
  • This question being "closed" is a bit mystifying to me. I go searching for "why do dictionary views exist?", find this question and the very informative answer, and am made to feel guilty for having asked a question that was deemed insufficiently focused. Seems pretty focused to me. – LondonRob Nov 17 '20 at 09:44

1 Answers1

2

Here is the official documentation, and PEP 3106 is the proposal inspired by the Java Collections Framework.

Dictionary views are returned by dict.keys(), dict.values() and dict.items() in Python 3. Backported to Python 2.7, you must directly call dict.viewkeys(), dict.viewvalues() and dict.viewitems().

Dictionary views are iterable like dicts, and they add memory improvements as they do not build lists when iterated. These perks are subtle and baked into the language.

One direct use case comes from dictionary key views being set-like.

From the docs:

dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
keys = dishes.keys()

keys & {'eggs', 'bacon', 'salad'}
# {'bacon'}

keys ^ {'sausage', 'juice'}
# {'juice', 'sausage', 'bacon', 'spam'}

In addition to normal set operations, this behavior simplifies testing whether two dictionaries share common keys.

See Brandon Rhodes' PyCon 2017 talk, The Dictionary Even Mightier on this topic.

pylang
  • 40,867
  • 14
  • 129
  • 121
  • I did some performance measurements comparing `d.viewkeys() & s` to `set(d) & s`: https://pastebin.com/4nLEvvkZ . It seems that using `viewkeys()` is slower by a factor of ~1.3. So this usecase is also not helpful as it is better done using `set(d)`. – Alfe Sep 21 '17 at 08:22
  • Thanks for your analysis. You may have misunderstood the use case. Note, I did not comment on speed. `d.viewkeys()` offers views to Python 2.7 in place of lists. You should test for memory. – pylang Sep 21 '17 at 22:38