我有一个很长的(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
答案 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)