accessing nested dict from list of keys [duplicate] - python

This question already has answers here:
Access nested dictionary items via a list of keys?
(20 answers)
Closed 3 years ago.
I have a a nested dict object with N layers:
d={'l0':{'l1':{'l2':...}}}
in addition, I have a list of all the dict keys:
k=['l0','l1','l2',...]
how can I access the element defined by the list,for an arbitrary list, that is:
d[k[0]][k[1]][k[2]].... = X
(I would like a function that return the reference to the data...)

One approach is the following:
def resolve_value(obj, keys):
for key in keys:
obj = obj[key]
return obj
k = ['l0', 'l1', 'l2']
d = {'l0': {'l1': {'l2': 'hello'}}}
print(resolve_value(d, k))
Output
hello

You can go with the intuitive solution:
val = d
for key in k:
val = val[key]
# operations with val here

Related

Is there a more efficient way to delete elements from a dictionary? [duplicate]

This question already has answers here:
filter items in a python dictionary where keys contain a specific string
(6 answers)
Closed 8 months ago.
d = {'a1':1, 'a2':2,'a3':3,'a4':1,'a5':1,'b':2, 'c':3}
for k, v in d.copy().items():
if 'a' in k:
del d[k]
print(d)
I want to delete elements if the key or value meets a certain requirement, as above, in which the keys containing 'a' will be deleted.
In particular, can I somehow not use the copy() function to do the same thing?
EDIT: Based on suggestion, I adopted this way:
for k in list(d):
if 'a' in k:
del d[k]
Create a new dictionary without the key you want to filter
d = {'a1':1, 'a2':2,'a3':3,'a4':1,'a5':1,'b':2, 'c':3}
filtered_d = {k: v for k,v in d.items() if 'a' not in k}

Creating a new dictionary with same key and values averaged from another dictionary in Python [duplicate]

This question already has answers here:
How can I calculate average of different values in each key of python dictionary?
(3 answers)
Closed 2 years ago.
I have an existing dictionary called StudentGrad that has the following data type:
('Aditya','male','senior'):[0.83,0.87,0.82,0.83],
('Varun','male','senior'):[0.76,0.86,0.88,0.79],
('Shantanu','male','senior'):[0.79,0.81,0.78,0.78],
I want to create a new dictionary called studentAvg that has the same keys, but returns an average grade for the values:
('Aditya','male','senior'):[0.84],
('Varun','male','senior'):[0.82],
('Shantanu','male','senior'):[0.79],
Any help would be appreciated....
Thanks!
Try to do this:
x = {('Aditya','male','senior'):[0.83,0.87,0.82,0.83],
('Varun','male','senior'):[0.76,0.86,0.88,0.79],
('Shantanu','male','senior'):[0.79,0.81,0.78,0.78]}
def average(data):
sum = 0
for elem in data:
sum+=elem
result = sum/len(data)
return result
y = {}
for elem in x:
y[elem] = average(x[elem])
You can use a dict comprehension and a custom function for averaging :
d1 = {('Aditya','male','senior'):[0.83,0.87,0.82,0.83],
('Varun','male','senior'):[0.76,0.86,0.88,0.79],
('Shantanu','male','senior'):[0.79,0.81,0.78,0.78],
}
def average(list_values):
"let's assume you want an arithmetic mean"
return sum(list_values) / len(list_values)
d2 = {k:average(val) for k, val in d1.items()}
And if you really want a list of the average (as stated in the question) :
d2 = {k:[average(val)] for k, val in d1.items()}
Try this:
studentAvg = {
('Aditya','male','senior'):sum(studendGrad["('Aditya','male','senior')"])/len(studendGrad["('Aditya','male','senior')"]),
('Varun','male','senior'):sum(studentGrad["(Varun','male','senior')"])/len(studentGrad["('Varun','male','senior')"]),
('Shantanu','male','senior'):sum(studentGrad["('Shantanu','male','senior')"]/len(studentGrad["('Shantanu','male','senior')"])
}

using dictionary comprehension for a new dict [duplicate]

This question already has answers here:
Create a dictionary with comprehension
(17 answers)
Closed 2 years ago.
Been informed this has been answered - apoligies
Thank you!
Since you wanted a function to perform this:
def newprice(d):
return {"all" + key: value * 5 for key, value in d.items()}
# To be used as :
dict1 = {'apple':5, 'banana':4}
print(newprice(dict1))
In dictionary comprehension you can do whatever you want to keys and values:
def newprice(d):
return {f'all{k}': v * 5 for k, v in d.items()}
Here you go -
dict1 = {'apple':5, 'banana':4}
dict2 = {('all'+ k): 5*dict1[k] for k in dict1 }
print(dict2)

How to append dict into dict using loop if specific key already have a dict [duplicate]

This question already has answers here:
How to create key or append an element to key?
(6 answers)
Closed 2 years ago.
i want to add dict on specific key but if there is already a dict on that key then it should append the dict on that specific key like this
graph = {
1:{2:3,3:4,4:7},
2:{3:1,6:5},
3:{6:6,4:2},
4:{5:3,7:6},
5:{7:3,8:4},
6:{5:1,8:8},
7:{8:2},
8:{7:2}
}
This is the format i want and i am using loop as,
graph= {}
def addEdge(u,v):
graph[u].append(v)
def add(key, value):
dic = {}
dic[key]=value
return dic
for i in range(0,20):
a=yy[i]
b=add(zz[i],xdist[i])
addEdge(a,b)
I am getting this error
graph[u].append(v)
KeyError: 1
Values are
a
Out[12]: 1
b
Out[13]: {2: 803}
graph
Out[14]: {}
I can not use graph[a] = b in for loop because as node 1 is connected to more than 1 node so in first iteration it adds dict 2:803 on key 1 and when it comes that 1 is also connected to 12 it over writes 2:803 I do not know how to append it.
Thanks in advance
You should check if the key is present in graph dict or not:
graph = {}
def addEdge(u, v):
if u in graph.keys():
graph[u].append(v)
else:
graph[u] = [v] #or graph[u] = v
OR
graph = {}
def addEdge(u, v):
if u in graph.keys():
graph[u].update(v)
else:
graph[u] = v

Merge a dict in Python using 1 dict as base [duplicate]

This question already has answers here:
How do I merge two dictionaries in a single expression in Python?
(43 answers)
Closed 5 years ago.
I am looking for feedback on my Python code. I am trying to merge two dictionaries. One of the dictionaries controls the structure and the default values, the second dictionary will overwrite the default values when applicable.
Please note that I am looking for the following behaviour:
keys only present in the other dict should not be added
nested dicts should be taken into account
I wrote this simple function:
def merge_dicts(base_dict, other_dict):
""" Merge two dicts
Ensure that the base_dict remains as is and overwrite info from other_dict
"""
out_dict = dict()
for key, value in base_dict.items():
if key not in other_dict:
# simply use the base
nvalue = value
elif isinstance(other_dict[key], type(value)):
if isinstance(value, type({})):
# a new dict myst be recursively merged
nvalue = merge_dicts(value, other_dict[key])
else:
# use the others' value
nvalue = other_dict[key]
else:
# error due to difference of type
raise TypeError('The type of key {} should be {} (currently is {})'.format(
key,
type(value),
type(other_dict[key]))
)
out_dict[key] = nvalue
return out_dict
I am sure this can be done more beautifully/pythonic.
If you're using python 3.5 or later you can simply do:
merged_dict = {**base_dict, **other_dict}
In case you're using any prior version you can do it with the update method:
merged_dict = {}
merged_dict.update(base_dict)
merged_dict.update(other_dict)
For more information about it you can check The Idiomatic Way to Merge Dictionaries in Python
"Pythonicness" is a hard measure to assess, but here is my take on it:
def merge_dicts(base_dict, other_dict):
""" Merge two dicts
Ensure that the base_dict remains as is and overwrite info from other_dict
"""
if other_dict is None:
return base_dict
t = type(base_dict)
if type(other_dict) != t:
raise TypeError("Mismatching types: {} and {}."
.format(t, type(other_dict)))
if not issubclass(t, dict):
return other_dict
return {k: merge_dicts(v, other_dict.get(k)) for k, v in base_dict.items()}
Example:
merge_dicts({"a":2, "b":{"b1": 5, "b2": 7}}, {"b": {"b1": 9}})
>>> {'a': 2, 'b': {'b1': 9, 'b2': 7}}

Categories