Iterating over dictionary items(), values(), keys() in Python 3

2024/11/19 21:21:38

If I understand correctly, in Python 2, iter(d.keys()) was the same as d.iterkeys(). But now, d.keys() is a view, which is in between the list and the iterator. What's the difference between a view and an iterator?

In other words, in Python 3, what's the difference between

for k in d.keys()f(k)

and

for k in iter(d.keys())f(k)

Also, how do these differences show up in a simple for loop (if at all)?

Answer

I'm not sure if this is quite an answer to your questions but hopefully it explains a bit about the difference between Python 2 and 3 in this regard.

In Python 2, iter(d.keys()) and d.iterkeys() are not quite equivalent, although they will behave the same. In the first, keys() will return a copy of the dictionary's list of keys and iter will then return an iterator object over this list, with the second a copy of the full list of keys is never built.

The view objects returned by d.keys() in Python 3 are iterable (i.e. an iterator can be made from them) so when you say for k in d.keys() Python will create the iterator for you. Therefore your two examples will behave the same.

The significance in the change of the return type for keys() is that the Python 3 view object is dynamic. i.e. if we say ks = d.keys() and later add to d then ks will reflect this. In Python 2, keys() returns a list of all the keys currently in the dict. Compare:

Python 3

>>> d = { "first" : 1, "second" : 2 }
>>> ks = d.keys()
>>> ks
dict_keys(['second', 'first'])
>>> d["third"] = 3
>>> ks
dict_keys(['second', 'third', 'first'])

Python 2.x

>>> d = { "first" : 1, "second" : 2 }
>>> ks = d.keys()
>>> ks
['second', 'first']
>>> d["third"] = 3
>>> ks
['second', 'first']

As Python 3's keys() returns the dynamic object Python 3 doesn't have (and has no need for) a separate iterkeys method.

Further clarification

In Python 3, keys() returns a dict_keys object but if we use it in a for loop context for k in d.keys() then an iterator is implicitly created. So the difference between for k in d.keys() and for k in iter(d.keys()) is one of implicit vs. explicit creation of the iterator.

In terms of another difference, whilst they are both dynamic, remember if we create an explicit iterator then it can only be used once whereas the view can be reused as required. e.g.

>>> ks = d.keys()
>>> 'first' in ks
True
>>> 'second' in ks
True
>>> i = iter(d.keys())
>>> 'first' in i
True
>>> 'second' in i
False             # because we've already reached the end of the iterator

Also, notice that if we create an explicit iterator and then modify the dict then the iterator is invalidated:

>>> i2 = iter(d.keys())
>>> d['fourth'] = 4
>>> for k in i2: print(k)
...
Traceback (most recent call last):File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

In Python 2, given the existing behaviour of keys a separate method was needed to provide a way to iterate without copying the list of keys whilst still maintaining backwards compatibility. Hence iterkeys()

https://en.xdnf.cn/q/26397.html

Related Q&A

Is there a method that tells my program to quit?

For the "q" (quit) option in my program menu, I have the following code:elif choice == "q":print()That worked all right until I put it in an infinite loop, which kept printing blank…

Hiding Axis Labels

Im trying to hide the axis labels on the first subplot at 211. Id like to label the figure, not just a subplot (reference: "Isub Event Characteristics"). How can I control font properties lik…

Why does Python preemptively hang when trying to calculate a very large number?

Ive asked this question before about killing a process that uses too much memory, and Ive got most of a solution worked out.However, there is one problem: calculating massive numbers seems to be untouc…

Django, name parameter in urlpatterns

Im following a tutorial where my urlpatterns are:urlpatterns = patterns(,url(r^passwords/$, PasswordListView.as_view(), name=passwords_api_root),url(r^passwords/(?P<id>[0-9]+)$, PasswordInstance…

The most Pythonic way of checking if a value in a dictionary is defined/has zero length

Say I have a dictionary, and I want to check if a key is mapped to a nonempty value. One way of doing this would be the len function:mydict = {"key" : "value", "emptykey"…

What does the --pre option in pip signify?

I saw on this page that pip install neo4j-doc-manager --pre was used. What does the --pre flag mean?

Tracing and Returning a Path in Depth First Search

So I have a problem that I want to use depth first search to solve, returning the first path that DFS finds. Here is my (incomplete) DFS function:start = problem.getStartState()stack = Stack()visited =…

Pandas OHLC aggregation on OHLC data

I understand that OHLC re-sampling of time series data in Pandas, using one column of data, will work perfectly, for example on the following dataframe:>>df ctime openbid 1443654000 1.1170…

Python plotting libraries [closed]

Closed. This question is seeking recommendations for books, tools, software libraries, and more. It does not meet Stack Overflow guidelines. It is not currently accepting answers.We don’t allow questi…

python elasticsearch client set mappings during create index

I can set mappings of index being created in curl command like this:{ "mappings":{ "logs_june":{ "_timestamp":{ "enabled":"true"},"properties&…