Yan*_*nis 4 python dictionary keyerror
我有一个字典dct
,我希望它的每个值都可以求和,只要它们在指定的列表中存在相应的键lst
.
我到目前为止使用的代码是:
sum(dct[k] for k in lst)
Run Code Online (Sandbox Code Playgroud)
在上面的生成器表达式中,我想处理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)
Run Code Online (Sandbox Code Playgroud)
另一种选择是lst
在迭代之前进行过滤:
sum(dct[k] for k in filter(lambda i: i in dct, lst))
Run Code Online (Sandbox Code Playgroud)
您可以在过滤列表上使用reduce 函数作为替代sum
:
reduce(lambda a, k: a + dct[k], filter(lambda i: i in dct, lst))
Run Code Online (Sandbox Code Playgroud)
现在让我们用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
Run Code Online (Sandbox Code Playgroud)
所以最快的选择是通过生成器表达式中的 if 语句对项目求和
sum(dct[k] for k in lst if k in dct) # Via sum and condition: 9.4715681076
Run Code Online (Sandbox Code Playgroud)
祝你好运 !
您有两种选择:
检查密钥是否存在
sum(dct[k] for k in lst if k in dct)
Run Code Online (Sandbox Code Playgroud)
或使用 get
sum(dct.get(k, 0) for k in lst)
Run Code Online (Sandbox Code Playgroud)
其中dct.get(k, 0)
返回dct[k]
如果k
是在一个关键的dct
还是0
,如果没有.