简体   繁体   中英

Merge an arbitrary number of dictionaries of lists

How could dictionaries whose values are lists be merged in Python, so that all of the keys are moved into one dictionary, and all the elements of each list moved into a single list for each key?

For example, with these dictionaries:

x = {'a': [2], 'b': [2]}
y = {'b': [11], 'c': [11]}

... the result of the merging should be like this:

{'a': [2], 'b': [2, 11], 'c': [11]}

How could this be done with any number of dictionaries, not just two?

You can use following approach, which uses sets and dict comprehension

x = {'a': [2], 'b': [2]} 
y = {'b': [11], 'c': [11]}

all_keys = set(x) | set(y)

print {k:x.get(k, [])+y.get(k, []) for k in all_keys}

Results:

{'a': [2], 'c': [11], 'b': [2, 11]}
for k, v in y.items():
    x.setdefault(k, []).extend(v)

To collect all the lists together, form a result dictionary that maps your keys to lists. The simplest way to do this is with dict.setdefault() followed by a call to list.extend to grow the lists:

r = {}
for d in [x, y]:
    for k, v in d.items():
        r.setdefault(k, []).extend(v)

A little more elegant way is with collections.defaultdict() where the automatic default is a new empty list:

from collections import defaultdict

r = defaultdict(list)
for d in [x, y]:
    for k, v in d.items():
        r[k].extend(v)

Here's a solution that works for an arbitrary number of dictionaries:

def collect(*dicts):
    result = {}
    for key in set.union(*(set(d) for d in dicts)):
        result[key] = sum((d.get(key, []) for d in dicts), [])
    return result

It's essentially a generalisation of Tanveer's answer, taking advantage of the fact that set.union() can accept any number of dictionaries as arguments.

Here's an example of the function in use:

>>> x = {'a': [2], 'b': [2]}
>>> y = {'b': [11], 'c': [11]}
>>> collect(x, y)
{'a': [2], 'c': [11], 'b': [2, 11]}

... and with multiple dictionaries:

>>> z = {'c': [12, 13], 'd': [5]}
>>> collect(x, y, z)
{'a': [2], 'c': [11, 12, 13], 'b': [2, 11], 'd': [5]}

 x = {'a': [2], 'b': [2]} y = {'b': [11], 'c': [11]} result = {} for key,value in x.iteritems(): result[key] = value for key,value in y.iteritems(): if key in result: for l in value: result[key].append(l) else: result[key] = value print result 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM