过滤Python生成器表达式中的值

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这个生成器表达式内的方法.

如果在字典中找不到列表中键,则它应该继续获取其他值.总和的最终结果不应受任何缺失键的影响.如果没有密钥存在,那么零应该是和的结果.

And*_*yko 6

嗯,有几个选项,首选之一是使用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)

祝你好运 !


Wom*_*atz 5

您有两种选择:

检查密钥是否存在

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,如果没有.