Python 字典列表合并

3
我希望将列表中键为'user'相同的字典合并,但我不知道如何实现。例如:
[{'count2': 34, 'user': 2},
 {'count4': 233, 'user': 2},
 {'count2': 234, 'user': 4},
 {'count4': 344, 'user': 5}]

would become:

[{'count2': 34, 'count4': 233, 'user': 2 },
 {'count2': 234, 'user': 4},
 {'count4': 344, 'user': 5}]

我在Stack Overflow上进行了广泛搜索,但没有找到类似的内容,希望能得到帮助。非常感谢。

1
用户索引的字典是否可行?例如,{2:{'count2':34 ...},4:{'count2':234 ...}等等。这样更加直观,并且构建起来可能更容易些。 - David Robinson
4个回答

7
from collections import defaultdict

dl = [{'count2': 34, 'user': 2},
{'count4': 233, 'user': 2},
{'count2': 234, 'user': 4},
{'count4': 344, 'user': 5}]
print dl

dd = defaultdict(dict)
for d in dl:
    dd[d['user']].update(d)
print dd.values()

3
你可以用dd[u].update(d)替换for k, v in d.items(): dd[u][k] = v,意思不变,但更加简洁。 - Lie Ryan

3
你可以先排序,然后使用groupby,最后合并它。
from itertools import groupby
def merge(dicts):
    ret = {}
    for d in dicts:
        ret.update(d)
    return ret

d = [...]
sorted_d = sorted(d, key=lambda x: x['user'])
grouped_d = itertools.groupby(sorted_d, key=lambda x: x['user'])
print [merge(y[1]) for y in grouped]

1

在数组中:

[{'count2': 34, 'user': 2},
 {'count4': 233, 'user': 2},
 {'count2': 234, 'user': 4},
 {'count4': 344, 'user': 5}]

假设 a = {'count2': 34, 'user': 2}b = {'count4': 233, 'user': 2}

dict(a.items() + b.items())

将返回:

{'count2': 34, 'count4': 233, 'user': 2 }

编辑:适用于团队:

http://codepad.org/ObWT2Hl3


2
这只合并其中的两个,而不是分组。 - David Robinson
1
我的意思是需要明确说明应该将哪些组合在一起;如果有数百个需要合并的字典,它就会不够用。但这是解决方案的一部分。 - David Robinson

1

类似这样的代码应该可以工作。但可能有更高效的方法来实现它(并且代码行数更少)...

# Input
a=[{'count2': 34, 'user': 2},
 {'count4': 233, 'user': 2},
 {'count2': 234, 'user': 4},
 {'count4': 344, 'user': 5}]

# Get set of unique users
u=list(set([x['user'] for x in a]))

# Create a blank list of dictionaries for the result
r=[{}] * len(u)

# Iterate over input and add the dictionaries together
for x in a:
    r[u.index(x['user'])] = dict(r[u.index(x['user'])].items() + x.items())


>>> r
[{'count2': 34, 'user': 2, 'count4': 233}, {'count2': 234, 'user': 4}, {'count4': 344, 'user': 5}]

1
输入应该叫作 a 而不是 i,对吧? - mgilson
1
@mgilson:是的,谢谢。我已经修复了它。我在从我的测试终端复制/粘贴时有点混乱。 - Lee Netherton
如果我想让列表中的结果字典具有相同的零键作为默认值,该怎么办?提前致谢。 - Arkantos
1
为此,最好找到所有唯一版本的“count *”键,并在r = [{}] * len(u)行中将它们初始化为0。 - Lee Netherton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接