Loop through all nested dictionary values?
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))
How to iterate through a nested dict?
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 :)
Loop through nested dictionary, replacing values with items from a list
Your dictionary comprehension is creating dictionary elements for every item in the list each time. But since you give them all the same key topic
, only the last one is in the resulting dictionary. That's why you keep getting "topic": 6
.
Use zip()
to iterate through the dictionary keys and list elements in parallel, rather than nesting them. And there's no need to use update()
if you're just setting one key of the dictionary, just assign to that key.
def update_dic(dictionary):
for k, v in zip(dictionary, topics):
dictionary[k]['topic'] = v
Iterate through nested dictionary values and return an ordered list based on dict's values
Try:
all_keys = set(k for v in transportation_cost.values() for k in v.keys())
out = {
k: [
*sorted(
transportation_cost.keys(), key=lambda x: transportation_cost[x][k]
)
]
for k in all_keys
}
print(out)
Prints:
{
"Huawei": ["Fac-2", "Fac-3", "Fac-5", "Fac-1", "Fac-4"],
"Motorolla": ["Fac-5", "Fac-3", "Fac-4", "Fac-2", "Fac-1"],
"Apple": ["Fac-4", "Fac-1", "Fac-5", "Fac-2", "Fac-3"],
"Nokia": ["Fac-3", "Fac-5", "Fac-4", "Fac-2", "Fac-1"],
"Samsung": ["Fac-2", "Fac-4", "Fac-1", "Fac-3", "Fac-5"],
}
How to loop through all nested dictionary to give all the parent key concatenated and its value
The answer of script0 results in an output that starts with a forward slash (/
). I modified script0's code a little:
def flatten(x, parent=''):
for key in x.keys():
if isinstance(x[key], dict) and parent == '': flatten(x[key], key)
elif isinstance(x[key], dict) and parent != '': flatten(x[key], f"{parent}/{key}")
elif not isinstance(x[key], dict) and parent == '': print(f"{key}: {x[key]}")
else: print(f"{parent}/{key}: {x[key]}")
dictionary= {'items': { 'heading': 'Maps','description':'Maps123','imagepath':'/music/images/','config':{'config1':12,'config2':123}},'db':{'username':'xyz','password':'xyz'},'version':'v1'}
flatten(dictionary)
Output (without the leading /):
items/heading: Maps
items/description: Maps123
items/imagepath: /music/images/
items/config/config1: 12
items/config/config2: 123
db/username: xyz
db/password: xyz
version: v1
Please note that you could also create a new dictionary with the left-hand side of the output as the keys and the right-hand side as the values.
For example:
new_dict = {}
def flatten(x, parent=''):
for key in x.keys():
if isinstance(x[key], dict) and parent == '': flatten(x[key], key)
elif isinstance(x[key], dict) and parent != '': flatten(x[key], f"{parent}/{key}")
elif not isinstance(x[key], dict) and parent == '': new_dict[key] = x[key]
else: new_dict[f"{parent}/{key}"] = x[key]
dictionary= {'items': { 'heading': 'Maps','description':'Maps123','imagepath':'/music/images/','config':{'config1':12,'config2':123}},'db':{'username':'xyz','password':'xyz'},'version':'v1'}
flatten(dictionary)
print(new_dict)
Output:
{'items/heading': 'Maps', 'items/description': 'Maps123', 'items/imagepath': '/music/images/', 'items/config/config1': 12, 'items/config/config2': 123, 'db/username': 'xyz', 'db/password': 'xyz', 'version': 'v1'}
How to iterate through an N-level nested dictionary in Python?
try out this code
it also supports a combination of levels
from typing import List, Tuple
def iterate_multilevel_dictionary(d: dict):
dicts_to_iterate: List[Tuple[dict, list]] = [(d, [])]
'''
the first item is the dict object and the second object is the prefix keys
'''
while dicts_to_iterate:
current_dict, suffix = dicts_to_iterate.pop()
for k, v in current_dict.items():
if isinstance(v, dict):
dicts_to_iterate.append((v, suffix + [k]))
else:
yield suffix + [k] + [v]
if __name__ == '__main__':
d_level1 = {"a": 1, "b": 2, "c": 3}
print(f"test for {d_level1}")
for items in iterate_multilevel_dictionary(d_level1):
print(items)
d_level2 = {"group_1": {"a": 1}, "group_2": {"b": 2, "c": 3}}
print(f"test for {d_level2}")
for items in iterate_multilevel_dictionary(d_level2):
print(items)
d_level3 = {"collection_1": d_level2}
print(f"test for {d_level3}")
for items in iterate_multilevel_dictionary(d_level3):
print(items)
d_level123 = {}
[d_level123.update(i) for i in [d_level1, d_level2, d_level3]]
print(f"test for {d_level123}")
for items in iterate_multilevel_dictionary(d_level123):
print(items)
the outputs is:
test for {'a': 1, 'b': 2, 'c': 3}
['a', 1]
['b', 2]
['c', 3]
test for {'group_1': {'a': 1}, 'group_2': {'b': 2, 'c': 3}}
['group_2', 'b', 2]
['group_2', 'c', 3]
['group_1', 'a', 1]
test for {'collection_1': {'group_1': {'a': 1}, 'group_2': {'b': 2, 'c': 3}}}
['collection_1', 'group_2', 'b', 2]
['collection_1', 'group_2', 'c', 3]
['collection_1', 'group_1', 'a', 1]
test for {'a': 1, 'b': 2, 'c': 3, 'group_1': {'a': 1}, 'group_2': {'b': 2, 'c': 3}, 'collection_1': {'group_1': {'a': 1}, 'group_2': {'b': 2, 'c': 3}}}
['a', 1]
['b', 2]
['c', 3]
['collection_1', 'group_2', 'b', 2]
['collection_1', 'group_2', 'c', 3]
['collection_1', 'group_1', 'a', 1]
['group_2', 'b', 2]
['group_2', 'c', 3]
['group_1', 'a', 1]
using recursion is another approach but I thought writing without recursion is more challenging and more efficient :)
How to iterate through a nested dictionary with varying depth, and make a copy with value representing the path?
The most efficient way to do this would be using the same recursive function to not generate excess performance overhead. To copy the dictionary you can use copy.deepcopy()
and then take that copy through the function, but replace the values instead of just printing the path:
import copy
data = {'n11': {'n12a': {'n13a': 10, 'n13b': "some text"}, 'n12b': {'n13c': {'n14a': 40}}}, 'n21': {'n22a': 20}}
def myreplace(d, path=[]):
for k, v in d.items():
if isinstance(v, dict):
myreplace(v, path + [k])
else:
print('_'.join(path + [k]))
d[k] = '_'.join(path + [k])
return d
copy_of_data = copy.deepcopy(data)
copy_of_data = myreplace(copy_of_data)
print(data)
print(copy_of_data)
I had to modify the original function slightly to get it working.
Python how to iterate over nested dictionary and change values?
You could use a dict
here to hold the price multipliers, and iterate through all orders with nested for loops.
exchanges = {
'exchange1': [{'price': 9656.04, 'side': 'bid', 'size': 0.16, 'timestamp': 1589504786},
{'price': 9653.97, 'side': 'ask', 'size': 0.021, 'timestamp': 1589504786}],
'exchange2': [{'price': 9755.3, 'side': 'bid', 'size': 27.0, 'timestamp': 1589504799},
{'price': 9728.0, 'side': 'bid', 'size': 1.0, 'timestamp': 1589504799}]
}
price_multipliers = {
'bid': 0.99,
'ask': 1.01
}
for orders in exchanges.values():
for order in orders:
order["price"] *= price_multipliers[order["side"]]
Iterating over nested dictionary returns only first element
The problem is that when you call return myPrint(v, k)
for the first time you compute the values for the first dictionary and then return instead of continuing to the other values in the for loop.
Changing the function to:
def myPrint(d, key=""):
output = {}
for k, v in d.items():
i = 0
if isinstance(v, dict):
output.update(myPrint(v, k))
else:
for value in d.values():
newkey = (f"{i}_{key}")
output[newkey] = value
i += 1
return output
will return a big dictionary, for you example:
{'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71],
'0_OuterVal1': [21, 19, 76], '1_OuterVal1': [1, 1, 1],
'0_OuterVal2': [1, 1, 96], '1_OuterVal2': [10, 9, 7],
'0_OuterVal3': [0, 2, 6], '1_OuterVal3': [1, 911, 718],
'0_OuterVal4': [12, 13, 9], '1_OuterVal4': [1000, 910, 701],
'0_OuterVal5': [110, 211, 961], '1_OuterVal5': [10, 911, 918]}
However, the function can be nicely packed in a non-recursive way as follow:
output = [{f'{ii}_{k}': vv for (k, v) in source.items() for ii, (kk, vv) in enumerate(v.items())}]
Related Topics
How to Import the Class Within the Same Directory or Sub Directory
What Is the Naming Convention in Python For Variable and Function
Standalone Python Applications in Linux
Python's Equivalent for R's Dput() Function
Redirecting Python's Stdout to the File Fails with Unicodeencodeerror
Pyodbc:Can't Open the Driver Even If It Exists
How to Make Shell Output Redirect (>) Write While Script Is Still Running
How to Send Input on Stdin to a Python Script Defined Inside a Makefile
Fitting Empirical Distribution to Theoretical Ones With Scipy (Python)
How to Get the Full Path of the Current File'S Directory
Multiprocessing: Use Only the Physical Cores
How to Setup Environment Variable R_User to Use Rpy2 in Python
Set the Hardware Clock in Python
Binding Callbacks to Minimize and Maximize Events in Toplevel Windows
Package Libffi Was Not Found in the Pkg-Config Search Path Redhat6.5