【发布时间】:2020-05-19 02:30:13
【问题描述】:
我试图找出从 dicts 列表中构建新 dict 的最佳方法,列表中的每个 dict 都有 2 个公共键,一个公共键值将是新 dict 的键和其他公共键值将是新字典中的值列表中的一个元素。
我设法提供了 4 种不同的解决方案,这是我的示例:
list_of_dicts = [
{'key_1': 'v2', 'key_2': 'some data 1', 'key_3': 'some random data'},
{'key_1': 'v1', 'key_2': 'some data 2'},
{'key_1': 'v1', 'key_2': 'some data 1'},
{'key_1': 'v2', 'key_2': 'some data 2'}]
使用 collections.defaultdict 的解决方案 1:
from collections import defaultdict
group_by_key_1 = defaultdict(list)
for d in list_of_dicts:
group_by_key_1[d['key_1']].append(d['key_2'])
group_by_key_1
输出 1:
defaultdict(list,
{'v2': ['some data 1', 'some data 2'],
'v1': ['some data 2', 'some data 1']})
使用 dict.setdefault 的解决方案 2:
group_by_key_1 = {}
for d in list_of_dicts:
group_by_key_1.setdefault(d['key_1'], []).append(d['key_2'])
group_by_key_1
输出 2:
{'v2': ['some data 1', 'some data 2'], 'v1': ['some data 2', 'some data 1']}
解决方案3,如果有任何元素,则追加或添加带有第一个元素的列表:
group_by_key_1 = {}
for d in list_of_dicts:
if d['key_1'] not in group_by_key_1:
group_by_key_1[d['key_1']] = [d['key_2']]
else:
group_by_key_1[d['key_1']].append(d['key_2'])
group_by_key_1
输出 3:
{'v2': ['some data 1', 'some data 2'], 'v1': ['some data 2', 'some data 1']}
解决方案 4,使用 itertools.groupby:
from itertools import groupby
from operator import itemgetter
list_of_dicts.sort(key=itemgetter('key_1'))
group = groupby(list_of_dicts, key=itemgetter('key_1'))
group_by_key_1 = dict((k, [e['key_2'] for e in v]) for k, v in group)
group_by_key_1
输出 4:
{'v1': ['some data 2', 'some data 1'], 'v2': ['some data 1', 'some data 2']}
通常,我使用解决方案 1,但解决方案 2 和 3 似乎也可以,但是,什么解决方案是最有效的方法?或者也许还有其他最好的解决方案?
我想对几百万个 list_of_dicts 使用上述解决方案之一,而 list_of_dicts 中的一个 dict 可以有 10 到 1000 个键。
【问题讨论】:
-
第一个
collections.defaultdict对我来说似乎是最干净、最易读的 -
这不是
itertools.groupby的用途吗?itertools是为高效的通用迭代技术/范式而创建的,您所做的事情仅通过名称groupby来解释。在这些情况下,这是我的首选。也就是说,我确实相信这个问题对答案留下了很多意见,因此可能不适合本网站。 -
#1 也可能是最快的。也是常见的不公社。
-
@Jab,这需要一种添加不必要的
O(nlogn)的排序。 -
对于解决方案 4,您可以使用字典理解:
{k: e['key_2'] for e in v for k, v in group}
标签: python list dictionary