简体   繁体   中英

Merge Dictionaries oin a list with the same key

I have a list of dicts , like this:

x = [{'a': 3}, {'b': 1}, {None: 0}, {'a': 1}, {'b': 1}, {None: 0}]

and I would like to have a something like this

x = [{'a': 4}, {'b': 2}, {None: 0}]

What is the most memory-friendly way to reach that?

You can also use collections.Counter , which will naturally update the counts:

from collections import Counter

l = [{'a': 3}, {'b': 1}, {None: 0}, {'a': 1}, {'b': 1}, {None: 0}]

counts = Counter()
for d in l:
    counts.update(d)

print([{k: v} for k, v in counts.items()])

From the docs for collections.Counter.update :

Elements are counted from an iterable or added-in from another mapping (or counter). Like dict.update() but adds counts instead of replacing them. Also, the iterable is expected to be a sequence of elements, not a sequence of (key, value) pairs.

You can also use a collections.defaultdict to do the counting:

from collections import defaultdict

l = [{'a': 3}, {'b': 1}, {None: 0}, {'a': 1}, {'b': 1}, {None: 0}]

counts = defaultdict(int)
for d in l:
    for k, v in d.items():
        counts[k] += v

print([{k: v} for k, v in counts.items()])

Or you could also count with initializing 0 yourself:

l = [{'a': 3}, {'b': 1}, {None: 0}, {'a': 1}, {'b': 1}, {None: 0}]

counts = {}
for d in l:
    for k, v in d.items():
        counts[k] = counts.get(k, 0) + 1

print([{k: v} for k, v in counts.items()])

From the docs for dict.get :

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError .

Output:

[{'a': 4}, {'b': 2}, {None: 0}]

Lets say:

l = [{'a': 3}, {'b': 1}, {None: 0}, {'a': 1}, {'b': 1}, {None: 0}]

Now we will extract and add up:

res = []
for k in l:
    for i in k:
        s = {i:sum(j[i] for j in l if i in j)}
        if s not in res:
            res.append(s)

gives:

[{'a': 4}, {'b': 2}, {None: 0}]

Or we could use (adapted from here ):

result = {}
for d in l:
    for k in d.keys():
        result[k] = result.get(k, 0) + d[k]
res = [{i:result[i]} for i in result]

Check the one-line code using pandas.

L = [{'a': 3}, {'b': 1}, {None: 0}, {'a': 1}, {'b': 1}, {None: 0}]
output = pd.DataFrame(L).sum(axis = 0).to_dict()

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