This question already has answers here:
Sum values of similar keys inside two nested dictionary in python
(2 answers)
Closed 1 year ago.
I have a list of dictionary:
data = [
{"2010" : {'A' : 2,'B' : 3,'C' : 5,}},
{"2011" : {'A' : 1,'B' : 2,}},
{"2010" : {'A' : 1,'B' : 2,}}
]
I'd like sum the values where the key is same. So the result I expected should be like this:
res =
{"2010" : {'A' : 3, 'B' : 5, 'C' : 5},
"2011" : {'A' : 1, 'B' : 2}}
How can I do this easily?
So you have a list of dictionaries as input and you want to create an output dictionary which contains the sums:
from collections import defaultdict
data = [{'2010': {'A': 2, 'B': 3, 'C': 5}}, {'2011': {'A': 1, 'B': 2}}, {'2010': {'A': 1, 'B': 2}}]
def sum_values(data):
out = {}
for i in data:
for k in i.keys():
if k not in out:
out[k] = defaultdict(int)
for k1,v1 in i[k].items():
out[k][k1] += v1
return out
sum_values(data)
{'2010': defaultdict(<class 'int'>, {'A': 3, 'B': 5, 'C': 5}), '2011': defaultdict(<class 'int'>, {'A': 1, 'B': 2})}
Try this
data = [
{ "2010":{'A':2,'B':3,'C':5,}},
{ "2011":{'A':1,'B':2,}},
{"2010":{'A':1,'B':2,}}
]
res = {}
for d in data:
# print(d.items())
items = list(d.items())[0] # convert to list because dict items isn't subscriptable
year, value = items
if year not in res:
res[year] = value
res is equal to
{
'2010': {'A': 2, 'B': 3, 'C': 5},
'2011': {'A': 1, 'B': 2}
}
Related
This question already has answers here:
Python Dictionary: How to update dictionary value, base on key - using separate dictionary keys
(2 answers)
Closed 1 year ago.
I have the following 2 dictionaries
a = {'a': 1, 'b': 2, 'c': 3}
b = {1: 11, 2: 22}
And I'd like to modify a into
a = {'a': 11, 'b': 22, 'c': 3}
How do I achieve this result?
You might use following dict-comprehension
a = {'a': 1, 'b': 2, 'c': 3}
b = {1: 11, 2: 22}
a = {k:b.get(v,v) for k,v in a.items()}
print(a)
output
{'a': 11, 'b': 22, 'c': 3}
Note usage of .get(v,v) so if there is not key in b original value is retained.
you can try dict comprehension
{k1: b.get(v1, v1) for k1,v1 in a.items()}
{'a': 11, 'b': 22, 'c': 3}
Try this:
a = {k: b.get(v, v) for k, v in a.items()}
try this:
a = {'a': 1, 'b': 2, 'c': 3}
b = {1: 11, 2: 22}
for k,v in a.items():
a[k] = b.get(v, v)
print(a)
Output:
{'a': 11, 'b': 22, 'c': 3}
This question already has answers here:
Python dict.fromkeys return same id element
(2 answers)
Closed 3 years ago.
I've a dict code snippets which is not behaving as expected
a = {"d1":{"a":1,"b":2,"c":4},"d2":{"a":1,"b":2,"c":4},"d3":{"a":1,"b":2,"c":4}}
b = {"d1":{"a":1,"b":0},"d2":{"a":0,"c":4},"d3":{"a":1,"b":2,"c":4}}
c = dict.fromkeys(a.keys(),{})
print(c)
for doc in b.keys():
for word in b[doc].keys():
c[doc][word] = a[doc][word]*b[doc][word]
print(c)
output is:
{'d1': {}, 'd2': {}, 'd3': {}}
{'d1': {'a': 1, 'b': 4, 'c': 16}, 'd2': {'a': 1, 'b': 4, 'c': 16}, 'd3': {'a': 1, 'b': 4, 'c': 16}}
instead of:
{'d1': {}, 'd2': {}, 'd3': {}}
{'d1': {'a': 1, 'b': 0}, 'd2': {'a': 0, 'c': 16}, 'd3': {'a': 1, 'b': 4, 'c': 16}}
I very confused now any insights would be helpful.
The problem is because you are using a mutable object as the second argument for fromkeys.
This is much clearer here:
d = dict.fromkeys(['a', 'b'], [])
d['a'].append(1)
print(d)
Outputs
{'a': [1], 'b': [1]}
Made a modification to your for loop :
for doc in b.keys():
for word in b[doc].keys():
if doc not in c:
c[doc]={}
c[doc][word] = a[doc][word]*b[doc][word]
print(c)
#{'d1': {'a': 1, 'b': 0}, 'd2': {'a': 0, 'c': 16}, 'd3': {'a': 1, 'b': 4, 'c': 16}}
Use a dictionary comprehension to create c instead:
c = {k: {} for k in a.keys()}
for doc in b.keys():
for word in b[doc].keys():
c[doc][word] = a[doc][word]*b[doc][word]
print(c)
# {'d1': {'a': 1, 'b': 0}, 'd2': {'a': 0, 'c': 16}, 'd3': {'a': 1, 'b': 4, 'c': 16}}
Notice the difference when you use fromkeys vs dictionary comprehension:
c = dict.fromkeys(a.keys(),{})
print([id(o) for o in c.values()])
# [53649152, 53649152, 53649152]
# same object reference id!
c = {k: {} for k in a.keys()}
print([id(o) for o in c.values()])
# [53710208, 53649104, 14445232]
# each object has different reference id
I am a beginner in python trying to create a function that filters through my nested dictionary through by asking multiple values in a dictionary like
filtered_options = {'a': 5, 'b': "Cloth'}
For my dictionary
my_dict = {1.0:{'a': 1, 'b': "Food', 'c': 500, 'd': 'Yams'},
2.0:{'a': 5, 'v': "Cloth', 'c': 210, 'd': 'Linen'}}
If I input my dictionary in the filter function with such options I should get something that looks like
filtered_dict(my_dict, filtered_options = {'a': 5, 'b': "Cloth'})
which outputs the 2nd key and other keys with the same filtered options in my dictionary.
This should do what you want.
def dict_matches(d, filters):
return all(k in d and d[k] == v for k, v in filters.items())
def filter_dict(d, filters=None):
filters = filters or {}
return {k: v for k, v in d.items() if dict_matches(v, filters)}
Here's what happens when you test it:
>>> filters = {'a': 5, 'b': 'Cloth'}
>>> my_dict = {
... 1.0: {'a': 1, 'b': 'Food', 'c': 500, 'd': 'Yams'},
... 2.0: {'a': 5, 'b': 'Cloth', 'c': 210, 'd': 'Linen'}
... }
>>> filter_dict(my_dict, filters)
{2.0: {'b': 'Cloth', 'a': 5, 'd': 'Linen', 'c': 210}}
You can do this :
import operator
from functools import reduce
def multi_level_indexing(nested_dict, key_list):
"""Multi level index a nested dictionary, nested_dict through a list of keys in dictionaries, key_list
"""
return reduce(operator.getitem, key_list, nested_dict)
def filtered_dict(my_dict, filtered_options):
return {k : v for k, v in my_dict.items() if all(multi_level_indexing(my_dict, [k,f_k]) == f_v for f_k, f_v in filtered_options.items())}
So that:
my_dict = {1.0:{'a': 1, 'b': 'Food', 'c': 500, 'd': 'Yams'},
2.0:{'a': 5, 'b': 'Cloth', 'c': 210, 'd': 'Linen'}}
will give you:
print(filtered_dict(my_dict, {'a': 5, 'b': 'Cloth'}))
# prints {2.0: {'a': 5, 'b': 'Cloth', 'c': 210, 'd': 'Linen'}}
Having a dict like:
x = {
'1': {'a': 1, 'b': 3},
'2': {'a': 2, 'b': 4}
}
I'd like to have a new key total with the sum of each key in the subdictionaries, like:
x['total'] = {'a': 3, 'b': 7}
I've tried adapting the answer from this question but found no success.
Could someone shed a light?
Assuming all the values of x are dictionaries, you can iterate over their items to compose your new dictionary.
from collections import defaultdict
x = {
'1': {'a': 1, 'b': 3},
'2': {'a': 2, 'b': 4}
}
total = defaultdict(int)
for d in x.values():
for k, v in d.items():
total[k] += v
print(total)
# defaultdict(<class 'int'>, {'a': 3, 'b': 7})
A variation of Patrick answer, using collections.Counter and just update since sub-dicts are already in the proper format:
from collections import Counter
x = {
'1': {'a': 1, 'b': 3},
'2': {'a': 2, 'b': 4}
}
total = Counter()
for d in x.values():
total.update(d)
print(total)
result:
Counter({'b': 7, 'a': 3})
(update works differently for Counter, it doesn't overwrite the keys but adds to the current value, that's one of the subtle differences with defaultdict(int))
You can use a dictionary comprehension:
x = {'1': {'a': 1, 'b': 3}, '2': {'a': 2, 'b': 4}}
full_sub_keys = {i for b in map(dict.keys, x.values()) for i in b}
x['total'] = {i:sum(b.get(i, 0) for b in x.values()) for i in full_sub_keys}
Output:
{'1': {'a': 1, 'b': 3}, '2': {'a': 2, 'b': 4}, 'total': {'b': 7, 'a': 3}}
from collections import defaultdict
dictionary = defaultdict(int)
x = {
'1': {'a': 1, 'b': 3},
'2': {'a': 2, 'b': 4}
}
for key, numbers in x.items():
for key, num in numbers.items():
dictionary[key] += num
x['total'] = {key: value for key, value in dictionary.items()}
print(x)
We can create a default dict to iterate through each of they key, value pairs in the nested dictionary and sum up the total for each key. That should enable a to evaluate to 3 and b to evaluate to 7. After we increment the values we can do a simple dictionary comprehension to create another nested dictionary for the totals, and make a/b the keys and their sums the values. Here is your output:
{'1': {'a': 1, 'b': 3}, '2': {'a': 2, 'b': 4}, 'total': {'a': 3, 'b': 7}}
Suppose I am give a list of dictionaries, where
dict1 = dict(a = 2, b = 5, c = 7)
dict2 = dict(c = 5, d = 5, e = 1)
dict3 = dict(e = 2, f = 4, g = 10)
list_of_dictionaries = [dict1, dict2, dict3]
How would I be able to, find the value of the highest index (aka the latest dictionary)?
So if I were to write a method to delete an item from the list of dictionaries, let's say I want to delete c from the dictionary.
How would I be able to delete the c from the second dictionary instead of the first?
The key is reversing through the list with reverse indexing (a_list[::-1]).
From there once you find any dictionary that matches the requirements alter it and quit the function or loop - hence the early returns.
This code:
def get_last(bucket,key):
for d in bucket[::-1]:
if key in d.keys():
return d[key]
return None
def set_last(bucket,key,val):
for d in bucket[::-1]:
if key in d.keys():
d[key] = val
return
def pop_last(bucket,key):
out = None
for d in bucket[::-1]:
if key in d.keys():
return d.pop(key)
dict1 = {'a': 2, 'b': 5, 'c': 7}
dict2 = {'c': 5, 'd': 5, 'e': 1}
dict3 = {'e': 2, 'f': 4, 'g': 10}
list_of_dictionaries = [dict1, dict2, dict3]
print get_last(list_of_dictionaries ,'c')
set_last(list_of_dictionaries ,'c',7)
print list_of_dictionaries
popped = pop_last(list_of_dictionaries ,'c')
print popped
print list_of_dictionaries
Gives:
5
[{'a': 2, 'c': 7, 'b': 5}, {'c': 7, 'e': 1, 'd': 5}, {'e': 2, 'g': 10, 'f': 4}]
7
[{'a': 2, 'c': 7, 'b': 5}, {'e': 1, 'd': 5}, {'e': 2, 'g': 10, 'f': 4}]
I am not exactly sure what you mean but I wan to show you a couple of things that might help:
First here is how your dictionaries should look like:
dict1 = {"a" :2, "b" : 5, "c" :7}
dict2 = {"c" :5, "d" :5, "e" :1}
dict3 = {"e" :2, "f" :4, "g" :10}
Then you asked this: "How would I be able to delete the c from the second dictionary instead of the first?"
You can do delete it this way:
del dict2["c"]