从大量的Dict列表中创建dict的最快方法

时间:2014-02-18 16:32:12

标签: python python-2.7 dictionary

我需要从大量的dict列表中创建一个字典,删除所有重复的dicts

输入列表如下:

input = [{'id': 1, 'value1': 'value1', 'value2': 'value2'},{'id': 2, 'value1': 'value1', 'value2': 'value2'}, {'id': 2, 'value1': 'value1', 'value3': 'value4'}]

我想创建一个这样的字典,使用" id"值作为新词典的关键:

output = {
    1: [{'id': 1, 'value1': 'value1', 'value2': 'value2'}]
    2: [{'id': 2, 'value1': 'value1', 'value2': 'value2'}, {'id': 2, 'value1': 'value1', 'value3': 'value4'}]
}

我的第一次尝试是:

    output = {}
    for el in input:
        if el['id'] not in output or el not in output[el['id']]:
            output.setdefault(el['id'], []).append(el)

它实际上有效,但它超级慢,len(输入)大约是20k / 30k项目

还有其他方法可以更快一点吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

使用单独的set来跟踪所见的词典;你必须先将它们转换为可散列的表示法:

seen = set()
drepr = lambda d: tuple(sorted(d.items()))

output = {}
for el in input:
    if drepr(el) not in seen:
        output.setdefault(el['id'], []).append(el)
        seen.add(drepr(el))

您可以使用collections.defaultdict object来加快速度,因为它会实现列表,而无需查找方法并推送堆栈帧来调用它:

from collections import defaultdict

seen = set()
drepr = lambda d: tuple(sorted(d.items()))

output = defaultdict(list)

for el in input:
    if drepr(el) not in seen:
        output[el['id']].append(el)
        seen.add(drepr(el))

演示:

>>> input = [{'id': 1, 'value1': 'value1', 'value2': 'value2'},{'id': 2, 'value1': 'value1', 'value2': 'value2'}, {'id': 2, 'value1': 'value1', 'value3': 'value4'}]
>>> seen = set()
>>> drepr = lambda d: tuple(sorted(d.items()))
>>> output = {}
>>> for el in input:
...     if drepr(el) not in seen:
...         output.setdefault(el['id'], []).append(el)
...         seen.add(drepr(el))
... 
>>> from pprint import pprint
>>> pprint(output)
{1: [{'id': 1, 'value1': 'value1', 'value2': 'value2'}],
 2: [{'id': 2, 'value1': 'value1', 'value2': 'value2'},
     {'id': 2, 'value1': 'value1', 'value3': 'value4'}]}

答案 1 :(得分:0)

使用重复的dicts创建一个新的输出列表,然后使新列表中的每个元素成为唯一的一组dicts

input=[{'id': 1, 'value1': 'value1', 'value2': 'value2'}, {'id': 2, 'value1': 'value1', 'value2': 'value2'}, {'value3': 'value4', 'id': 2, 'value1': 'value1'}, {'id': 2, 'value1': 'value1', 'value2': 'value2'}]

output={}
for el in input: output.setdefault(el['id'], []).append(el)
for key in output:
    output[key]=map(dict, set(tuple(sorted(d.items())) for d in output[key]))

print output

[{'id': 2, 'value1': 'value1', 'value2': 'value2'}, {'value3': 'value4', 'id': 2, 'value1': 'value1'}]