How to iterate through a nested dict?
Question:
I have a nested python dictionary
data structure. I want to read its keys and values without
using collection
module. The data structure is like bellow.
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
I was trying to read the keys in the dictionary using the bellow way but getting error.
Code
for key, value in d:
print(Key)
Error
ValueError: too many values to unpack (expected 2)
So can anyone please explain the reason behind the error and how to iterate through the dictionary.
Answers:
To get keys and values you need dict.items()
:
for key, value in d.items():
print(key)
If you want just the keys:
for key in d:
print(key)
Iterating through a dictionary only gives you the keys.
You told python to expect a bunch of tuples, and it tried to unpack something that wasn’t a tuple (your code is set up to expect each iterated item to be of the form (key,value)
, which was not the case (you were simply getting key
on each iteration).
You also tried to print Key
, which is not the same as key
, which would have led to a NameError
.
for key in d:
print(key)
should work.
keys()
method returns a view object that displays a list of all the keys in the dictionary
Iterate nested dictionary:
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
for i in d.keys():
print i
for j in d[i].keys():
print j
OR
for i in d:
print i
for j in d[i]:
print j
output:
dict1
foo
bar
dict2
baz
quux
where i
iterate main dictionary key and j
iterate the nested dictionary key.
As the requested output, the code goes like this
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
for k1,v1 in d.iteritems(): # the basic way
temp = ""
temp+=k1
for k2,v2 in v1.iteritems():
temp = temp+" "+str(k2)+" "+str(v2)
print temp
In place of iteritems()
you can use items()
as well, but iteritems()
is much more efficient and returns an iterator.
Hope this helps 🙂
You could use benedict
(a dict
subclass) and the traverse utility method:
Installation: pip install python-benedict
from benedict import benedict
d = benedict({'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}})
def traverse_item(dct, key, value):
print('key: {} - value: {}'.format(key, value))
d.traverse(traverse_item)
Documentation: https://github.com/fabiocaccamo/python-benedict
Note: I am the author of this project.
if given dictionary pattern has monotone format and keys are known
dict_ = {'0': {'foo': 1, 'bar': 2}, '1': {'foo': 3, 'bar': 4}}
for key, val in dict_.items():
if isinstance(val, dict):
print(val.get('foo'))
print(val.get('bar'))
in this case we can skip nested loop
you can iterate all keys and values of nested dictionary as following:
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
for i in d:
for j, k in d[i].items():
print(j,"->", k)
Your output looks like this –
foo -> 1
bar -> 2
baz -> 3
quux -> 4
The following will work with multiple levels of nested-dictionary:
def get_all_keys(d):
for key, value in d.items():
yield key
if isinstance(value, dict):
yield from get_all_keys(value)
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'dict3': {'baz': 3, 'quux': 4}}}
for x in get_all_keys(d):
print(x)
This will give you:
dict1
foo
bar
dict2
dict3
baz
quux
I have a nested python dictionary
data structure. I want to read its keys and values without
using collection
module. The data structure is like bellow.
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
I was trying to read the keys in the dictionary using the bellow way but getting error.
Code
for key, value in d:
print(Key)
Error
ValueError: too many values to unpack (expected 2)
So can anyone please explain the reason behind the error and how to iterate through the dictionary.
To get keys and values you need dict.items()
:
for key, value in d.items():
print(key)
If you want just the keys:
for key in d:
print(key)
Iterating through a dictionary only gives you the keys.
You told python to expect a bunch of tuples, and it tried to unpack something that wasn’t a tuple (your code is set up to expect each iterated item to be of the form (key,value)
, which was not the case (you were simply getting key
on each iteration).
You also tried to print Key
, which is not the same as key
, which would have led to a NameError
.
for key in d:
print(key)
should work.
keys()
method returns a view object that displays a list of all the keys in the dictionary
Iterate nested dictionary:
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
for i in d.keys():
print i
for j in d[i].keys():
print j
OR
for i in d:
print i
for j in d[i]:
print j
output:
dict1
foo
bar
dict2
baz
quux
where i
iterate main dictionary key and j
iterate the nested dictionary key.
As the requested output, the code goes like this
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
for k1,v1 in d.iteritems(): # the basic way
temp = ""
temp+=k1
for k2,v2 in v1.iteritems():
temp = temp+" "+str(k2)+" "+str(v2)
print temp
In place of iteritems()
you can use items()
as well, but iteritems()
is much more efficient and returns an iterator.
Hope this helps 🙂
You could use benedict
(a dict
subclass) and the traverse utility method:
Installation: pip install python-benedict
from benedict import benedict
d = benedict({'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}})
def traverse_item(dct, key, value):
print('key: {} - value: {}'.format(key, value))
d.traverse(traverse_item)
Documentation: https://github.com/fabiocaccamo/python-benedict
Note: I am the author of this project.
if given dictionary pattern has monotone format and keys are known
dict_ = {'0': {'foo': 1, 'bar': 2}, '1': {'foo': 3, 'bar': 4}}
for key, val in dict_.items():
if isinstance(val, dict):
print(val.get('foo'))
print(val.get('bar'))
in this case we can skip nested loop
you can iterate all keys and values of nested dictionary as following:
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
for i in d:
for j, k in d[i].items():
print(j,"->", k)
Your output looks like this –
foo -> 1
bar -> 2
baz -> 3
quux -> 4
The following will work with multiple levels of nested-dictionary:
def get_all_keys(d):
for key, value in d.items():
yield key
if isinstance(value, dict):
yield from get_all_keys(value)
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'dict3': {'baz': 3, 'quux': 4}}}
for x in get_all_keys(d):
print(x)
This will give you:
dict1
foo
bar
dict2
dict3
baz
quux