在Python中有效地创建(播种)大型词典

时间:2014-01-17 21:05:17

标签: python performance search dictionary

我有一个很长的(500K +行)两列电子表格,如下所示:

Name    Code
1234    A
1234    B
1456    C
4556    A
4556    B
4556    C
...

因此,有一个元素(带有名称)可以有许多代码。但是,每个代码不是一行,而是希望列出每个元素发生的所有代码。我想要的是这样的字典:

{"1234":["A","B"],"1456":["C"],"4556":["A","B","C"] ...]}

我试过的是这个(我不包括文件读取语法)。


    codelist = {}
    for row in rows:
        name,code = well.split()
        if name in codelist.keys():
            codelist[name].append(code)
        else:
            codelist[name] = [code]

这会创建正确的输出,但进度变得非常慢。所以我尝试用键启动我的字典:

allnames = [.... list of all the names ...]
codelist = dict.fromkeys(allnames)

for row in rows:

    name,code = well.split()
    if codelist[name]:
        codelist[name].append(code)
    else:
        codelist[name] = [code]

这快得多,我的问题是为什么?每次程序是否仍然必须搜索dict中的所有键?还有另一种方法可以加速不包括遍历树的字典搜索吗?

有趣的是我在使用相同的条件检查后得到的错误(如果在codelist.keys():)中引用我的字典之后的名字。

Traceback (most recent call last):
  File .... 
    codelist[name].append(code)
AttributeError: 'NoneType' object has no attribute 'append'

现在,有一个键但没有要附加的列表。所以我使用的codelist[name]也是<NoneType>,似乎也可以使用。 mydict["primed key"]<NoneType>时是什么意思?enter code here

2 个答案:

答案 0 :(得分:6)

前者速度较慢,因为.keys()必须首先在内存中创建所有键的列表,然后in运算符对其执行搜索。因此,对文本文件中的每一行进行O(N)搜索,因此速度很慢。

另一方面,简单的key in dict搜索需要O(1)次。

  

dict.fromkeys(allnames)

dict.fromkeys分配的默认值为None,因此您无法在其上使用append

>>> d = dict.fromkeys('abc')
>>> d
{'a': None, 'c': None, 'b': None}

更好的解决方案是在这里使用collections.defaultdict,如果不是一个选项,则使用普通的dict使用简单的if-else检查或dict.setdefault


在Python3 .keys()中返回一个View对象,因此时间复杂度可能会有所不同。但是,它仍然会比正常的key in dict搜索稍微慢一些。

答案 1 :(得分:2)

您可能希望查看defaultdict容器以避免检查

from collections import defaultdict

allnames [.... list of all the names ...]
codelist = defaultdict(list)

for row in rows:

    name,code = well.split()
    codelist[name].append(code)