Skip to main content
 首页 » 编程设计

Python加速: checking if value in list

2025年05月04日8softidea

我有一个处理 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], 
 ] 

我正在构建一个看起来像的字典

my_dict = { 
 'id_A': ['many', 'values'], 
 'id_B': ['many', ''more', 'values'] 
 'id_C': ['some', 'other', 'values']} 

我目前的实现看起来像

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:]) 

csv 中有将近一百万行,一旦字典中有几千个条目,程序就会开始显着变慢。我一直在用一些打印语句调试它,瓶颈似乎在 if log_id not in my_dict.keys(): 行

我尝试使用单独的 list 来跟踪字典中已有的 ID,但这似乎没有帮助。

在这里使用 set 是否可行,或者该选项是否可行,因为它会更改每个循环并需要重建?

请您参考如下方法:

您每次都在创建所有键的列表。删除 dict.keys()打电话,它会减慢你的速度,但不需要:

if log_id not in my_dict: 

字典直接支持成员资格测试,并且在 O(1) 时间内完成。 dict.keys() 返回一个新列表,但是,对列表的成员资格测试效率不高(需要 O(N) 时间)。因此,对于每个成员资格测试,您的代码将遍历所有 键以生成一个新的列表对象,然后再次遍历该列表以找到匹配项。

您可以使用 dict.setdefault() 稍微简化您的代码:

for line in lines: 
    log_id = line[0] 
    my_dict.setdefault(log_id, []).append(lines[1:]) 

dict.setdefault() 返回与给定键关联的值,如果缺少键,则使用第二个参数作为默认值(将键和值添加到字典中)。

或者,使用 collections.defaultdict() object而不是你的普通字典:

from collections import defaultdict 
 
mydict = defaultdict(list) 
 
for line in lines: 
    log_id = line[0] 
    my_dict[log_id].append(lines[1:]) 

defaultdict 是一个简单的 dict 子类,每当缺少一个键时,它都会调用配置的工厂;这里 list() 会在您尝试访问一个键时被调用,为丢失的键创建一个新值。