Using .iteritems() to iterate over key, value in Python dictionary
Question:
Note: I have read this post and Alex Martelli’s response, but I don’t really/fully understand his answer. It’s a bit beyond my current understanding. I would like help understanding it better.
I understand that when you try the following for loop:
for key, value in dict:
print key
print value
you get:
ValueError: too many values to unpack
Although you can loop over a dictionary and just get the keys with the following:
for key in dict:
print key
Can anyone provide a slightly less-advanced explanation for why you cannot iterate over a dictionary using key, value without using .iteritems()
?
Answers:
Python has a feature called iterable unpacking. When you do
a, b = thing
Python assumes thing
is a tuple or list or something with 2 items, and it assigns the first and second items to a
and b
. This also works in a for
loop:
for a, b in thing:
is equivalent to
for c in thing:
a, b = c
except it doesn’t create that c
variable.
This means that if you do
for k, v in d:
Python can’t look at the fact that you’ve said k, v
instead of k
and give you items instead of keys, because maybe the keys are 2-tuples. It has to iterate over the keys and try to unpack each key into the k
and v
variables.
The other answer explains it well. But here are some further illustrations for how it behaves, by showing cases where it actually works without error (so you can see something):
>>> d = {(1,2): 3, (4,5): 6}
>>> for k, v in d:
print k, v
1 2
4 5
The loop goes through the keys (1,2)
and (4,5)
and since those “happen to be” tuples of size 2, they can be assigned to k
and v
.
Works with strings as well, as long as they have exactly two characters:
>>> d = {"AB":3, "CD":6}
>>> for k, v in d:
print k, v
A B
C D
I assume in your case it was something like this?
>>> d = {"ABC":3, "CD":6}
>>> for k, v in d:
print k, v
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
for k, v in d:
ValueError: too many values to unpack
Here, the key “ABC” is a triple and thus Python complains about trying to unpack it into just two variables.
While using for xx in XX
, you are actually using an iterator to iterates the XX, and XX must be iterable. You can use iter
function to get an iterator, as
>>> d = dict(a=1,b=2)
>>> i = iter(d)
>>> i
<dictionary-keyiterator object at 0x6ffff8739f0>
and using next
to access the elements.
>>> next(i)
'a'
So in every iteration of for k in d
, k
will be assigned to next(i)
, and it’s only the key without value. e.g., in the first round of iteration,
k = 'a'
While .iteritems()
will return another iterator with can get a tuple of key-value combined. Let’s check this
>>> i = d.iteritems()
>>> i
<dictionary-itemiterator object at 0x6ffff873998>
>>> next(i)
('a', 1)
See? In the first round of for k, v in d.iteritems()
, we actually get this assignment
k, v = ('a', 1)
Thus, if you using for k, v in d
, you will get
k, v = 'a'
That’s an illegal assignment.
In Python 2.7.6 it seems that you may want to check for subproperties of the dictionary with dict.has_key(property_name)
.
In Python 3 you can use items() to get a list of tuple pairs from the dictionary. So you can iterate over this list:
for key, value in dict.items():
print key
print value
Note: I have read this post and Alex Martelli’s response, but I don’t really/fully understand his answer. It’s a bit beyond my current understanding. I would like help understanding it better.
I understand that when you try the following for loop:
for key, value in dict:
print key
print value
you get:
ValueError: too many values to unpack
Although you can loop over a dictionary and just get the keys with the following:
for key in dict:
print key
Can anyone provide a slightly less-advanced explanation for why you cannot iterate over a dictionary using key, value without using .iteritems()
?
Python has a feature called iterable unpacking. When you do
a, b = thing
Python assumes thing
is a tuple or list or something with 2 items, and it assigns the first and second items to a
and b
. This also works in a for
loop:
for a, b in thing:
is equivalent to
for c in thing:
a, b = c
except it doesn’t create that c
variable.
This means that if you do
for k, v in d:
Python can’t look at the fact that you’ve said k, v
instead of k
and give you items instead of keys, because maybe the keys are 2-tuples. It has to iterate over the keys and try to unpack each key into the k
and v
variables.
The other answer explains it well. But here are some further illustrations for how it behaves, by showing cases where it actually works without error (so you can see something):
>>> d = {(1,2): 3, (4,5): 6}
>>> for k, v in d:
print k, v
1 2
4 5
The loop goes through the keys (1,2)
and (4,5)
and since those “happen to be” tuples of size 2, they can be assigned to k
and v
.
Works with strings as well, as long as they have exactly two characters:
>>> d = {"AB":3, "CD":6}
>>> for k, v in d:
print k, v
A B
C D
I assume in your case it was something like this?
>>> d = {"ABC":3, "CD":6}
>>> for k, v in d:
print k, v
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
for k, v in d:
ValueError: too many values to unpack
Here, the key “ABC” is a triple and thus Python complains about trying to unpack it into just two variables.
While using for xx in XX
, you are actually using an iterator to iterates the XX, and XX must be iterable. You can use iter
function to get an iterator, as
>>> d = dict(a=1,b=2)
>>> i = iter(d)
>>> i
<dictionary-keyiterator object at 0x6ffff8739f0>
and using next
to access the elements.
>>> next(i)
'a'
So in every iteration of for k in d
, k
will be assigned to next(i)
, and it’s only the key without value. e.g., in the first round of iteration,
k = 'a'
While .iteritems()
will return another iterator with can get a tuple of key-value combined. Let’s check this
>>> i = d.iteritems()
>>> i
<dictionary-itemiterator object at 0x6ffff873998>
>>> next(i)
('a', 1)
See? In the first round of for k, v in d.iteritems()
, we actually get this assignment
k, v = ('a', 1)
Thus, if you using for k, v in d
, you will get
k, v = 'a'
That’s an illegal assignment.
In Python 2.7.6 it seems that you may want to check for subproperties of the dictionary with dict.has_key(property_name)
.
In Python 3 you can use items() to get a list of tuple pairs from the dictionary. So you can iterate over this list:
for key, value in dict.items():
print key
print value