我想知道你们是否可以给我一些关于使我的代码性能更好的建议。
我有一组for循环,它们查看一个键是否在一个字典中,其值是一个列表,如果该键存在,它会附加到列表中,如果它没有,它会为其添加一个新列表那把钥匙
dict={}
for value in value_list:
if value.key in dict.keys():
temp_list = dict[value.key]
temp_list.append(value.val)
dict[value.key] = temp_list
else:
dict[value.key] = [value.val]
现在这段代码工作得很好,但是随着字典开始填满dict.keys()中的行值.key变得越来越麻烦。
有更好的方法吗?
谢谢,
麦克
答案 0 :(得分:42)
不要这样做:
value.key in dict.keys()
那 - 在Python 2中,至少 - 创建一个包含每个键的列表。随着字典变大,这变得越来越昂贵,并且在列表上执行O(n)搜索以找到密钥,这违背了使用字典的目的。
相反,只需:
value.key in dict
不会创建临时列表,并为密钥而不是线性搜索执行哈希表查找。
如其他地方所述, setdefault
是更清洁的方法,但理解上述内容非常重要。
答案 1 :(得分:4)
使用collections.defaultdict
,可以简化为
d = collections.defaultdict(list)
for value in value_list:
d[value.key].append(value.val)
答案 2 :(得分:4)
your_dict.setdefault(value.key, []).append(value.val)
答案 3 :(得分:2)
if value.key in dict.keys():
非常昂贵,因为您正在转换为密钥列表,然后搜索列表。只需将其替换为:
if value.key in dict:
应该将搜索缩短到~log N(编辑:我的立场由 Glenn 更正,可能更快,因为Python词典使用哈希表)。然后简单地说:
dict[key].append(value.val)
应该加快速度。不需要使用临时值,只需吃一些CPU周期。
如果您可以提供有关您尝试做什么的更多详细信息,则可能会建议更好的算法。
答案 4 :(得分:2)
步骤1:我们使用temp_list将代码转换为单个表达式(我假设在此代码之外不需要temp_list
),使用加法而不是append
方法。此外,我们不需要像其他人一样明确地使用dict.keys()
(事实上它浪费了大量的时间)。
for value in value_list:
if value.key in dict:
dict[value.key] = dict[value.key] + [value.val]
else:
dict[value.key] = [value.val]
步骤2:使用条件表达式语法将赋值转换为相同位置。
for value in value_list:
dict[value.key] = dict[value.key] + [value.val] if value.key in dict else [value.val]
步骤3:追加或添加空列表对列表的值没有影响,因此我们可以插入该值,然后将该值的常用“加法”分解出来。
for value in value_list:
dict[value.key] = (dict[value.key] if value.key in dict else []) + [value.val]
步骤4:识别dict具有内置功能,以便在密钥不存在时提供“默认”值:
for value in value_list:
dict[value.key] = dict.get(value.key, []) + [value.val]
步骤5:我们可以使用.setdefault
向我们提供当前内容(或者如果尚未设置它们),而不是获取值,修改它并将其设置回来,然后切换回使用.append
修改列表:
for value in value_list:
dict.setdefault(value.key, []).append(value.val)
(我的意思是......我本来可以看一下它并想了一下然后到了这里,但看到每一步都会让我们更清楚......)