0

I need to merge a series of dictionaries:

dict1 = {u'electronica ': 12.0, u'art rock ': 14.0, u'chillout ': 12.0, u'genius ': 14.0, u'trip-hop ': 11.0, u'psychedelic ': 12.0, u'indie pop ': 11.0, u'ambient ': 12.0, u'indie rock ': 15.0, u'post-rock ': 11.0, u'alternative rock ': 15.0, u'seen live ': 12.0, u'melancholic ': 14.0, u'Awesome ': 15.0, u'radiohead ': 19.0, u'emo ': 10.0, u'rock ': 16.0, u'indie ': 13.0, u'90s ': 5.0, u'pop ': 12.0, u'britpop ': 13.0, u'british ': 17.0, u'classic rock ': 12.0, u'better than radiohead ': 12.0, u'overrated ': 12.0, u'alternative ': 14.0, u'Progressive ': 13.0, u's ': 7.0, u'Favorite ': 12.0, u'electronic ': 13.0, u'Experimental Rock ': 13.0, u'beautiful ': 14.0, u'melancholy ': 14.0, u'idm ': 12.0, u'Progressive rock ': 12.0, u'favorites ': 12.0, u'english ': 12.0, u'male vocalists ': 13.0, u'experimental ': 12.0, u'UK ': 14.0}
dict2 = {u'west coast': 26.0, u'hip hop': 24.0, u'rap': 19.0, u'gansta rap': 24.0}
dict3 = {u'hip hop': 26.0, u'west coast': 28.0, u'rap': 21.0, u'gansta rap': 26.0}
dict4 = {u'electronica ': 53.0, u'art rock ': 55.0, u'chillout ': 53.0, u'90s ': 5.0, u'trip-hop ': 52.0, u'psychedelic ': 53.0, u'ambient ': 53.0, u'Awesome ': 56.0, u'post-rock ': 52.0, u'alternative rock ': 56.0, u'seen live ': 53.0, u'melancholic ': 55.0, u'indie rock ': 56.0, u'melancholy ': 55.0, u'male vocalists ': 54.0, u'alternative ': 55.0, u'rock ': 57.0, u'indie ': 54.0, u'genius ': 55.0, u'pop ': 53.0, u'britpop ': 54.0, u'british ': 58.0, u'classic rock ': 53.0, u'better than radiohead ': 53.0, u'overrated ': 53.0, u'emo ': 51.0, u'Progressive ': 54.0, u's ': 48.0, u'Favorite ': 53.0, u'electronic ': 54.0, u'Experimental Rock ': 54.0, u'beautiful ': 55.0, u'radiohead ': 60.0, u'idm ': 53.0, u'Progressive rock ': 53.0, u'favorites ': 53.0, u'english ': 53.0, u'indie pop ': 52.0, u'experimental ': 53.0, u'UK ': 55.0}

I could use this function to do so:

def merge_dicts(*dict_args):

    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result

but then I would lose track of repeated keys (which happen often in the example).

Instead, I must merge dicts adding the values of repeated keys, because values here are weights.

how do I achieve that?

8-Bit Borges
  • 9,643
  • 29
  • 101
  • 198

2 Answers2

3

I would use a collections.Counter:

In [9]: ds = [dict1, dict2, dict3, dict4]

In [10]: from collections import Counter

In [11]: result = Counter()

In [12]: for d in ds:
    ...:     result.update(d)
    ...:

And the result:

In [13]: result
Out[13]:
Counter({'90s ': 10.0,
         'Awesome ': 71.0,
         'Experimental Rock ': 67.0,
         'Favorite ': 65.0,
         'Progressive ': 67.0,
         'Progressive rock ': 65.0,
         'UK ': 69.0,
         'alternative ': 69.0,
         'alternative rock ': 71.0,
         'ambient ': 65.0,
         'art rock ': 69.0,
         'beautiful ': 69.0,
         'better than radiohead ': 65.0,
         'british ': 75.0,
         'britpop ': 67.0,
         'chillout ': 65.0,
         'classic rock ': 65.0,
         'electronic ': 67.0,
         'electronica ': 65.0,
         'emo ': 61.0,
         'english ': 65.0,
         'experimental ': 65.0,
         'favorites ': 65.0,
         'gansta rap': 50.0,
         'genius ': 69.0,
         'hip hop': 50.0,
         'idm ': 65.0,
         'indie ': 67.0,
         'indie pop ': 63.0,
         'indie rock ': 71.0,
         'male vocalists ': 67.0,
         'melancholic ': 69.0,
         'melancholy ': 69.0,
         'overrated ': 65.0,
         'pop ': 65.0,
         'post-rock ': 63.0,
         'psychedelic ': 65.0,
         'radiohead ': 79.0,
         'rap': 40.0,
         'rock ': 73.0,
         's ': 55.0,
         'seen live ': 65.0,
         'trip-hop ': 63.0,
         'west coast': 54.0})

Alternatively, if you'd rather not use Counter:

In [14]: result = {}

In [15]: for d in ds:
    ...:     for k in d:
    ...:         result[k] = result.get(k, 0) + d[k]
    ...:

In [16]: result
Out[16]:
{'90s ': 10.0,
 'Awesome ': 71.0,
 'Experimental Rock ': 67.0,
 'Favorite ': 65.0,
 'Progressive ': 67.0,
 'Progressive rock ': 65.0,
 'UK ': 69.0,
 'alternative ': 69.0,
 'alternative rock ': 71.0,
 'ambient ': 65.0,
 'art rock ': 69.0,
 'beautiful ': 69.0,
 'better than radiohead ': 65.0,
 'british ': 75.0,
 'britpop ': 67.0,
 'chillout ': 65.0,
 'classic rock ': 65.0,
 'electronic ': 67.0,
 'electronica ': 65.0,
 'emo ': 61.0,
 'english ': 65.0,
 'experimental ': 65.0,
 'favorites ': 65.0,
 'gansta rap': 50.0,
 'genius ': 69.0,
 'hip hop': 50.0,
 'idm ': 65.0,
 'indie ': 67.0,
 'indie pop ': 63.0,
 'indie rock ': 71.0,
 'male vocalists ': 67.0,
 'melancholic ': 69.0,
 'melancholy ': 69.0,
 'overrated ': 65.0,
 'pop ': 65.0,
 'post-rock ': 63.0,
 'psychedelic ': 65.0,
 'radiohead ': 79.0,
 'rap': 40.0,
 'rock ': 73.0,
 's ': 55.0,
 'seen live ': 65.0,
 'trip-hop ': 63.0,
 'west coast': 54.0}
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
0

In Python Dict you are not allow to give duplicate key.If you give same key second time then system will override first value with second value.

One Solution is you need to create list of values.

ex: {key:[value,value,value]}

You can find Best example from below link.

List of values for duplicate keys in dictionary Python

Community
  • 1
  • 1