The following will work with multiple levels of nested-dictionary:
Copydef 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:
Copydict1
foo
bar
dict2
dict3
baz
quux
Answer from 0x0 on Stack OverflowThe following will work with multiple levels of nested-dictionary:
Copydef 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:
Copydict1
foo
bar
dict2
dict3
baz
quux
keys() method returns a view object that displays a list of all the keys in the dictionary
Iterate nested dictionary:
Copyd = {'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
Copyfor i in d:
print i
for j in d[i]:
print j
output:
Copydict1
foo
bar
dict2
baz
quux
where i iterate main dictionary key and j iterate the nested dictionary key.
python - Loop through all nested dictionary values? - Stack Overflow
How to loop through a nested dictionary
How to loop over nested dictionaries of n length?
python - How to iterate through this nested dictionary within a list using for loop - Stack Overflow
Videos
As said by Niklas, you need recursion, i.e. you want to define a function to print your dict, and if the value is a dict, you want to call your print function using this new dict.
Something like :
def myprint(d):
for k, v in d.items():
if isinstance(v, dict):
myprint(v)
else:
print("{0} : {1}".format(k, v))
There are potential problems if you write your own recursive implementation or the iterative equivalent with stack. See this example:
dic = {}
dic["key1"] = {}
dic["key1"]["key1.1"] = "value1"
dic["key2"] = {}
dic["key2"]["key2.1"] = "value2"
dic["key2"]["key2.2"] = dic["key1"]
dic["key2"]["key2.3"] = dic
In the normal sense, nested dictionary will be a n-nary tree like data structure. But the definition doesn't exclude the possibility of a cross edge or even a back edge (thus no longer a tree). For instance, here key2.2 holds to the dictionary from key1, key2.3 points to the entire dictionary(back edge/cycle). When there is a back edge(cycle), the stack/recursion will run infinitely.
root<-------back edge
/ \ |
_key1 __key2__ |
/ / \ \ |
|->key1.1 key2.1 key2.2 key2.3
| / | |
| value1 value2 |
| |
cross edge----------|
If you print this dictionary with this implementation from Scharron
def myprint(d):
for k, v in d.items():
if isinstance(v, dict):
myprint(v)
else:
print "{0} : {1}".format(k, v)
You would see this error:
> RuntimeError: maximum recursion depth exceeded while calling a Python object
The same goes with the implementation from senderle.
Similarly, you get an infinite loop with this implementation from Fred Foo:
def myprint(d):
stack = list(d.items())
while stack:
k, v = stack.pop()
if isinstance(v, dict):
stack.extend(v.items())
else:
print("%s: %s" % (k, v))
However, Python actually detects cycles in nested dictionary:
print dic
{'key2': {'key2.1': 'value2', 'key2.3': {...},
'key2.2': {'key1.1': 'value1'}}, 'key1': {'key1.1': 'value1'}}
"{...}" is where a cycle is detected.
As requested by Moondra this is a way to avoid cycles (DFS):
def myprint(d):
stack = list(d.items())
visited = set()
while stack:
k, v = stack.pop()
if isinstance(v, dict):
if k not in visited:
stack.extend(v.items())
else:
print("%s: %s" % (k, v))
visited.add(k)
Hiya, I'm developing a game as a hobby, and I am currently coding in a clothing shop. Every piece of clothing has a description, cost, and stat requirements. To organise this data, I've used nested dictionaries within a few class attributes.
Now I want the shopkeeper to have specific comment for some clothing brought, so I'd want to return/print the description every time a player buys a piece of clothing? How would I do that exactly?
My pseudo code/problem strategy has been to write a function, initiate a loop over the keys of the outer dictionary, then using a conditional to find the piece of clothing just brought, and looping through it's inner dictionary to find it's dictionary key, and printing out it's value, which is a string. Hope that helps you understand my thinking.
Hey there,
I have an dictionary (essentially json) and I'm trying to iterate over it. I cant share the dictionary but essentially i dont know how many times it will be nested. If it isn't nested there is data i need to return. Issue is depending on one of the values, it might have another dictionary i need to loop over. I'm having trouble conceptualizing how to even write this.
The stupid in me pictures it as a for loop for each nest (just assume ill never see a nesting of more than 10) and write the outputs i need to another list. I think the better way to handle this is recursion but I'm not super confident with it.
Is there any other way i can access all items of each nest without knowing how many nests?
Sorry if this is very arbitrary. I'm having difficulty myself even trying to explain it.
Cheers
You don't need to iterate through the keys in the dictionary (the inner for-loop), just access the value you want.
vid = [{'a':{'display':'axe', 'desc':'red'}, 'b':{'confidence':'good'} },
{'a':{'display':'book', 'desc':'blue'}, 'b':{'confidence':'poor'}},
{'a':{'display':'apple', 'desc':'green'}, 'b':{'confidence':'good'}}
]
new_dict = {}
list_of_dicts = []
for x in range(len(vid)):
desc = vid[x]['a']['desc']
list_of_dicts.append({'desc': desc})
I have found a temporary solution for this. I decided to use the pandas dataframe instead.
df = pd.DataFrame(columns = ['Desc'])
for x in range(len(vid)):
desc = vid[x]['a']['desc']
df.loc[len(df)] = [desc]