Bri*_*ach 1 python optimization
我有一个处理csv文件的程序.CSV的内容如下
lines = [
[id_A, val1, val2, ..., valn],
[id_A, val1, val2, ..., valn],
[id_B, val1, val2, ..., valn],
[id_B, val1, val2, ..., valn],
[id_B, val1, val2, ..., valn],
[id_B, val1, val2, ..., valn],
[id_C, val1, val2, ..., valn],
[id_C, val1, val2, ..., valn],
]
Run Code Online (Sandbox Code Playgroud)
我正在建立一个看起来像的字典
my_dict = {
'id_A': ['many', 'values'],
'id_B': ['many', ''more', 'values']
'id_C': ['some', 'other', 'values']}
Run Code Online (Sandbox Code Playgroud)
我目前的实现看起来像
for line in lines:
log_id = line[0]
if log_id not in my_dict.keys():
datablock = lines[1:]
my_dict[log_id] = datablock
else:
my_dict[log_id].append(lines[1:])
Run Code Online (Sandbox Code Playgroud)
在csv中接近一百万行,一旦字典中有几千个条目,程序开始显着减慢.我一直在打印报表的飞溅调试它,和瓶颈似乎是这里的if log_id not in my_dict.keys():
行
我尝试使用单独的字符list
来跟踪字典中已经存在的ID,但这似乎没有帮助.
可以set
在这里使用,或者是那个选项,因为它改变每个循环并需要重建?
Mar*_*ers 12
您每次都在创建所有键的列表.移除dict.keys()
呼叫,它会减慢您的速度,但不需要:
if log_id not in my_dict:
Run Code Online (Sandbox Code Playgroud)
字典直接支持成员资格测试,并在O(1)时间内完成.但是,dict.keys()
返回一个新列表,并且列表上的成员资格测试效率不高(需要O(N)时间).因此,对于每个成员资格测试,您的代码将循环遍历所有键以生成新的列表对象,然后再次遍历该列表以查找匹配项.
您可以使用dict.setdefault()
以下方法简化代码:
for line in lines:
log_id = line[0]
my_dict.setdefault(log_id, []).append(lines[1:])
Run Code Online (Sandbox Code Playgroud)
dict.setdefault()
返回与给定键关联的值,如果缺少键,则使用第二个参数作为默认值(将键和值添加到字典中).
或者,使用collections.defaultdict()
对象而不是普通字典:
from collections import defaultdict
mydict = defaultdict(list)
for line in lines:
log_id = line[0]
my_dict[log_id].append(lines[1:])
Run Code Online (Sandbox Code Playgroud)
A defaultdict
是一个简单的dict
子类,每次缺少一个键时都会调用配置的工厂; 这里list()
被调用为您尝试访问密钥时创建缺失密钥的新值.