我有一个字典dct
,我希望对其中的每个值进行求和,前提是它们对应的键存在于指定列表lst
中。
目前我使用的代码如下:
sum(dct[k] for k in lst)
在上述生成器表达式中,我希望处理
KeyError
,以防列表中的键在字典中找不到。我无法找到如何在此生成器表达式中实现(语法方面)try-except
方法或if-else
方法。如果列表中的键未在字典中找到,则应继续获取其他值。总和的最终结果不应受任何缺失键的影响。如果没有键存在,则总和的结果应为零。
我有一个字典dct
,我希望对其中的每个值进行求和,前提是它们对应的键存在于指定列表lst
中。
目前我使用的代码如下:
sum(dct[k] for k in lst)
KeyError
,以防列表中的键在字典中找不到。我无法找到如何在此生成器表达式中实现(语法方面)try-except
方法或if-else
方法。好的,有几种选项,首选是使用 dict.get()
:
# 1
sum(dct.get(k, 0) for k in lst)
# 2
sum(dct[k] for k in lst if k in dct)
另一个选项是在迭代 lst
之前对其进行过滤:
sum(dct[k] for k in filter(lambda i: i in dct, lst))
你可以使用 reduce 函数 作为 sum
的替代品来处理过滤后的列表:
reduce(lambda a, k: a + dct[k], filter(lambda i: i in dct, lst))
现在让我们使用timeit找到最快的方法:
from timeit import timeit
import random
lst = range(0, 10000)
dct = {x:x for x in lst if random.choice([True, False])}
via_sum = lambda:(sum(dct.get(k, 0) for k in lst))
print("Via sum and get: %s" % timeit(via_sum, number=10000))
# Via sum and get: 16.725695848464966
via_sum_and_cond = lambda:(sum(dct[k] for k in lst if k in dct))
print("Via sum and condition: %s" % timeit(via_sum_and_cond, number=10000))
# Via sum and condition: 9.4715681076
via_reduce = lambda:(reduce(lambda a, k: a + dct[k], filter(lambda i: i in dct, lst)))
print("Via reduce: %s" % timeit(via_reduce, number=10000))
# Via reduce: 19.9522120953
sum(dct[k] for k in lst if k in dct) # Via sum and condition: 9.4715681076
祝你好运!
sum(dct[k] for k in lst if k in dct)
get
。sum(dct.get(k, 0) for k in lst)
dct.get(k, 0)
是一个用于Python字典的方法,如果k
是字典dct
的键,则返回对应的值dct[k]
,否则返回默认值0
。
sum(dct[k] for k in lst if k in dct)
.get()
尝试从字典中获取键的值,如果未找到,则返回None
或您提供的默认参数,在本例中为0。>>> dct = {1:2, 3:4, 5:6}
>>> lst = [1,5]
>>> sum(dct.get(k, 0) for k in lst)
8
>>> lst = [10, 11]
>>> sum(dct.get(k, 0) for k in lst)
0
get
方法,在未找到时提供默认值:sum(dct.get(k, 0) for k in lst)
try
。为什么不使用dct.get(k)
,如果未找到键,则会返回None
而不是错误?如果未找到键,您的代码的正确行为是什么(例如,应将其视为0
)? - jonrsharpe