How can I concatenate dicts (values to values of the same key and new key)? [duplicate]
Asked Answered
I

3

7

I have a problem with concatenating dictionaries. Have so much code so I show in example what my problem is.

d1 = {'the':3, 'fine':4, 'word':2}
+
d2 = {'the':2, 'fine':4, 'word':1, 'knight':1, 'orange':1}
+
d3 = {'the':5, 'fine':8, 'word':3, 'sequel':1, 'jimbo':1}
=
finald = {'the':10, 'fine':16, 'word':6, 'knight':1, 'orange':1, 'sequel':1, 'jimbo':1}

It is prepering wordcounts for wordcloud. I dont know how to concatenate values of the keys it is puzzle for me. Please help. Best regards

Isidora answered 8/12, 2016 at 21:12 Comment(1)
Welcome to Stack Overflow! Please review How to Ask and show us what you've tried!Colloquy
C
8

I would use a Counter from collections for this.

from collections import Counter

d1 = {'the':3, 'fine':4, 'word':2}
d2 = {'the':2, 'fine':4, 'word':1, 'knight':1, 'orange':1}
d3 = {'the':5, 'fine':8, 'word':3, 'sequel':1, 'jimbo':1}

c = Counter()
for d in (d1, d2, d3):
    c.update(d)
print(c)

Outputs:

Counter({'fine': 16, 'the': 10, 'word': 6, 'orange': 1, 'jimbo': 1, 'sequel': 1, 'knight': 1})
Criss answered 8/12, 2016 at 21:18 Comment(2)
Counters seems to solve a lot of dict questions these days! For this problem I would do reduce(lambda x,y:Counter(x)+Counter(y),[d1,d2, d3]) . Is update() quicker/better than adding the counters?Stifle
@Stifle Probably not by much, if at all, and reduce is deprecated in python 3. I had originally written this with map(c.update, (d1, d2, d3)) but then I my inner functional programmer refused to allow me to abuse side effects like that.Criss
M
2
import itertools

d1 = {'the':3, 'fine':4, 'word':2}
d2 = {'the':2, 'fine':4, 'word':1, 'knight':1, 'orange':1}
d3 = {'the':5, 'fine':8, 'word':3, 'sequel':1, 'jimbo':1}
dicts = [d1, d2, d3]

In [31]: answer = {k:sum(d[k] if k in d else 0 for d in dicts) for k in itertools.chain.from_iterable(dicts)}

In [32]: answer
Out[32]: 
{'sequel': 1,
 'the': 10,
 'fine': 16,
 'jimbo': 1,
 'word': 6,
 'orange': 1,
 'knight': 1}
Mayor answered 8/12, 2016 at 21:15 Comment(4)
what about 'knight', 'sequel', 'orange', and 'jimbo'?Mesotron
@InspectorGadget well done!Mesotron
omg thanks nice oneliner :)Isidora
Why the downvote?Mayor
M
2
def sumDicts(*dicts):
    summed = {}
    for subdict in dicts:
        for (key, value) in subdict.items():
            summed[key] = summed.get(key, 0) + value
    return summed

Shell example:

>>> d1 = {'the':3, 'fine':4, 'word':2}
>>> d2 = {'the':2, 'fine':4, 'word':1, 'knight':1, 'orange':1}
>>> d3 = {'the':5, 'fine':8, 'word':3, 'sequel':1, 'jimbo':1}
>>> sumDicts(d1, d2, d3)
{'orange': 1, 'the': 10, 'fine': 16, 'jimbo': 1, 'word': 6, 'knight': 1, 'sequel': 1}
Mesotron answered 8/12, 2016 at 21:17 Comment(4)
if key in summed... would probably be better off as summed[key] = summed.get(key, 0) + valueMillymilman
@SeanMcSomething that does not work on my computer... says "can't assign to function call"Mesotron
Sorry, got some things mixed up. Fixed in edit.Millymilman
@SeanMcSomething fixed!Mesotron

© 2022 - 2024 — McMap. All rights reserved.