Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Understanding dictionary view objects

I've been trying to understand built-in view objects return by .items(), .values(), .keys() in Python 3 or similarly by .viewitems(), .viewvalues(), .viewkeys(). There are other threads on that subject but none (even the doc) seems to described how they work internally.

The main gain here seems to be efficienty compared to the copy of type list returned in Python 2. There are often compared to a window to the dictionnary items (like in this thread).

But what is that window and why is it more efficient ?

The only thing I can see is that the view objects seems to be set-like objects, which are generally faster for membership testing. But is this the only factor ?

Code sample

>>> example_dict = {'test':'test'}
>>> example_dict.items()
dict_items([('test', 'test')])
>>> type(example_dict.items())
<class 'dict_items'>

So, my question is regarding this dict_items class. How does that work internally?

like image 627
scharette Avatar asked Nov 13 '17 20:11

scharette


People also ask

How do you access items in a dictionary?

To access all values in a dictionary in Python, call the values() method. This is the quick answer.

How do you display data from a dictionary in Python?

values() is an inbuilt method in Python programming language that returns a view object. The view object contains the values of the dictionary, as a list. If you use the type() method on the return value, you get “dict_values object”.

Can Python dictionary have objects?

A dictionary value can be any type of object Python supports, including mutable types like lists and dictionaries, and user-defined objects, which you will learn about in upcoming tutorials.

What is a dictionary view?

Dictionary views are essentially what their name says: views are simply like a window on the keys and values (or items) of a dictionary.


2 Answers

Dict views store a reference to their parent dict, and they translate operations on the view to corresponding operations on the dict.

Iteration over a dict view is more efficient than building a list and iterating over that, because building a list takes time and memory that you don't have to spend with the view. The old way, Python would iterate over the dict's underlying storage to build a new list, and then you would iterate over the list. Iterating over a dict view uses an iterator that walks through the dict's underlying storage directly, skipping the unnecessary list step.

Dict views also support efficient containment tests and setlike intersection/difference/etc. operations, because they get to perform direct hash lookups on the underlying dict instead of iterating through a list and checking equality element by element.

If you want to see the concrete implementation used by CPython, you can take a look in the official repository, but this implementation is subject to change. It has changed, repeatedly.

like image 177
user2357112 supports Monica Avatar answered Nov 02 '22 16:11

user2357112 supports Monica


One of the main advantages is that views are dynamic:

>>> di={1:'one',2:'two',3:'three'}
>>> view=di.viewitems()
>>> view
dict_items([(1, 'one'), (2, 'two'), (3, 'three')])
>>> di[2]='new two'
>>> view
dict_items([(1, 'one'), (2, 'new two'), (3, 'three')])

Therefore you do not need to regenerate the item, key or value list (as you would with dict.items()) if the dictionary changes.

Think of the Python 2 dict.items() as a type of copy of the dict -- the way it was when the copy was made.

Think of Python 3 dict.items() or the Python 2 equivalent of dict.viewitems() as an up-to-date copy of the way the dict is now. (Same with .viewkeys(), .viewvalues() obviously.)

The Python 3.6 documents have good examples of why and when you would use one.

Value views are not set-like, since dicts can have duplicate values. Key views are set-like, and items views are set-like for dicts with hashable values.

Note: With Python 3, the view replaces what Python 2 had with .keys() .values() or .items() Some may relying on dict.keys() or dict.values() being a static representation of a dict's previous state may have a surprise.

like image 35
dawg Avatar answered Nov 02 '22 17:11

dawg