I've two dictionaries one original & the other reference. And I want to match reference dict keys with original dict keys and extract all those keys, values from original which are present in reference.
For example
original_dict = {
'a': {
'1': [1, 2, 3, 4, 5]
},
'b': {
'1': {
'A': [1, 2, 3, 4]
}
},
'c': {
'3': [1]
}
}
And a reference dictionary
reference_dict = {
'a': {
'2': [1, 2, 3]
},
'b': {
'1': {
'A': []
}
},
'c': {
'3': []
}
}
And this is the extracted dictionary.
extracted_dict = {
'b': {
'1': {
'A': [1, 2, 3, 4]
}
},
'c': {
'3': [1]
}
}
Here you might have noticed that I don't care about values of reference dict. All I want is the values of original dict.
You can use recursion to accomplish this:
def merge(value_dict, key_dict):
ret = {}
for key, subdict in key_dict.items():
if key in value_dict:
if not isinstance(value_dict[key], dict):
# we found a value so don't keep recursing
ret[key] = value_dict[key]
else:
# found another dict so merge subdicts
merged = merge(value_dict[key], subdict)
if len(merged) > 0:
ret[key] = merged
return ret
merge(original_dict, reference_dict)
I´m not sure if I understand your question 100% but this might be a solution.
we use relevant keys and put them in a list to use them on a .update() dict
new_lst = []
for i in original_dict.keys():
new_lst.append(original_dict[i])
reference_dict.clear()
for i in new_lst:
reference_dict.update(i)
print(reference_dict)
Related
Assuming that I have a nested dictionary, that is extracted from pickle file, that contains various levels, I would like to get the value by giving only the last key. Keys are unique considering own 'branch'.
The main problem is that I have multiple keys and levels:
dict = {
'A': {
'X': {
1: [...],
2: [...]
},
'Y': {
3: [...],
4: [...]
}
}
'B': {
'G': {
'H': {
'Z': [...]
}
}
}
'C': [...]
}
How can I do that?
a simple solution would be a recusrive function that even works for nested, nested dictionarys
outer_dict = {'outer': {'inner': 10, 'even_inner': {'innerst': 25}}}
and the function:
def get_val(search_dict, key):
""" recursive searching the dict """
for elem in search_dict:
if elem == key:
return search_dict[elem]
if isinstance(search_dict[elem], dict):
retval = get_val(search_dict[elem], key)
if retval is not None:
return retval
value = get_val(outer_dict, 'innerst')
print(value)
>> 25
Problems:
if the key is not unique you will get only the first match. You will need a list to fill a values into if the key can be there more than once.
Please provide a example next time!
I have a dict:
a = {
"group_a/category_a/metric_a": 5,
"group_a/category_a/metric_b": 4,
"group_a/category_b/metric_a": 3,
"group_a/category_b/metric_b": 2,
"group_b/category_a/metric_d": 1
}
I would like to unpack the nodes by creating a nested view, seperated by each slash, where the outcome looks as follows:
b = {
"group_a": {
"category_a": {
"metric_a": 5,
"metric_b": 4
},
"category_b": {
"metric_a": 3,
"metric_b": 2
},
"group_b": {
"category_a": {
"metric_d": 1
}
}
}
How can we go from a to b? I encountered this problem when trying to publish the dict above to Firebase as the nodes group_a/category_a/metric_a is not accepted, whereas a dict that is nested is allowed.
Loop through, split each key into a list of keys, create sub-dictionaries as required...
from pprint import pprint
a = {
"group_a/category_a/metric_a": 5,
"group_a/category_a/metric_b": 4,
"group_a/category_b/metric_a": 3,
"group_a/category_b/metric_b": 2,
"group_b/category_a/metric_d": 1
}
b = {}
for k, v in a.items():
dct = b
keys = k.split("/")
for key in keys[:-1]:
if key not in dct:
dct[key] = {}
dct = dct[key]
dct[keys[-1]] = v
pprint(b)
Gives:
{'group_a': {'category_a': {'metric_a': 5, 'metric_b': 4},
'category_b': {'metric_a': 3, 'metric_b': 2}},
'group_b': {'category_a': {'metric_d': 1}}}
Consider a dictionary,
dictionary = {
'AE':{'Applied':4, 'Programming':3 },
'BE':{'Applied':4, 'Programming':2 },
'CE':{'Applied':4, 'Programming':5 },
}
With comprehension in definition, yield the output as,
output = [['AE':'BE':'CE'],
['Applied', 2,4,5],
['Programming', 5,3,2]]
You can use this code:
dictionary = {
'AE':{'Applied':4, 'Programming':3 },
'BE':{'Applied':4, 'Programming':2 },
'CE':{'Applied':4, 'Programming':5 },
}
output = []
dict_keys = list(dictionary.keys())
output.append(dict_keys)
for key in dictionary[dict_keys[0]]:
value = [dictionary[k][key] for k in dict_keys]
value.insert(0, key)
output.append(value)
Output:
output = [['AE', 'BE', 'CE'], ['Applied', 4, 4, 4], ['Programming', 3, 2, 5]]
If I have a deeply nested dict is there a built-in way to subtract/remove list of "paths" (eg: keyA.keyB.key1, keyA.keyC.key2, etc) or a the keys of a second dict from the original dict? Or maybe there is a common module which has functionality like this?
Here's a suggestion:
D = { "keyA": {
"keyB" : {
"keyC" : 42,
"keyD": 13
},
"keyE" : 55
}
}
def remove_path(dictionary, path):
for node in path[:-1]:
dictionary = dictionary[node]
del dictionary[path[-1]]
remove_path(D, ["keyA", "keyB", "keyD"])
print D # prints {'keyA': {'keyB': {'keyC': 42}, 'keyE': 55}}
You'll probably want to introduce some error checking, too.
Just in case the other answers aren't what you're looking for, here's one that subtracts one dictionary from another.
def subtract(a, b):
""" Remove the keys in b from a. """
for k in b:
if k in a:
if isinstance(b[k], dict):
subtract(a[k], b[k])
else:
del a[k]
Another solution:
d = {
'A' : {
'C' : {
'D' : {
'E' : 4,
},
'F' : 5,
},
},
'B' : 2,
}
def DeepDictDel(path, dict):
for key in path.split('.'):
owner = dict
dict = dict[key]
del owner[key]
print d # prints {'A': {'C': {'D': {'E': 4}, 'F': 5}}, 'B': 2}
DeepDictDel('A.C.D', d)
print d # prints {'A': {'C': {'F': 5}}, 'B': 2}
I have a dict, that looks like this:
{
'foo': {
'opt1': 1,
'opt2': 2,
},
'foo/bar': {
'opt3': 3,
'opt4': 4,
},
'foo/bar/baz': {
'opt5': 5,
'opt6': 6,
}
}
And I need to get it to look like:
{
'foo': {
'opt1': 1,
'opt2': 2,
'bar': {
'opt3': 3,
'opt4': 4,
'baz': {
'opt5': 5,
'opt6': 6,
}
}
}
}
I should point out that there can and will be multiple top-level keys ('foo' in this case). I could probably throw something together to get what i need, but I was hoping that there is a solution that's more efficient.
Like this:
def nest(d):
rv = {}
for key, value in d.iteritems():
node = rv
for part in key.split('/'):
node = node.setdefault(part, {})
node.update(value)
return rv
def layer(dict):
for k,v in dict:
if '/' in k:
del dict[k]
subdict = dict.get(k[:k.find('/')],{})
subdict[k[k.find('/')+1:]] = v
layer(subdict)
Got this lib to print your dict in a better way. pprint.
https://docs.python.org/3.2/library/pprint.html