过滤Python生成器表达式中的值 [英] Filter values inside Python generator expressions
问题描述
我有一个字典 dct
,我希望将其每个值相加,只要它们的相应键存在于指定的列表中 lst
。
I have a dictionary dct
for which I want each of its values to be summed provided their corresponding keys exist in a specified list lst
.
我目前使用的代码是:
sum(dct[k] for k in lst)
在上述生成器表达式I想要处理 KeyError
,以防在列表中没有找到字典内的键。我似乎找不到如何实现(语法上) try
- 除了
方法,也不是如果
- else
此生成器表达式内的方法。
In the above generator expression I would like to handle the KeyError
in case a key from the list is not found inside the dictionary. I cannot seem to find how to implement (syntax-wise) either a try
-except
approach, nor an if
-else
approach inside this generator expression.
如果字典中没有找到列表中的键,则应继续获取其他值。 总和的最终结果不应受任何缺少的键的影响。如果没有键存在,那么零应该是总和的结果。
In case a key from the list is not found inside the dictionary, then it should carry on getting the other values. The end result of the sums should not be affected by any missing keys. In case none of the keys exist, then zero should be the sum's result.
推荐答案
嗯,有几个选项,首选一个是使用 dict.get()
:
Well, there are few options, preferred one is to use 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
,然后再重复一遍:
Also one of the option is to filter lst
before iteraring over it:
sum(dct[k] for k in filter(lambda i: i in dct, lst))
您可以使用减少功能在过滤列表中作为 sum
的替代方案:
And you can use reduce function on filtered list as an alternative to sum
:
reduce(lambda a, k: a + dct[k], filter(lambda i: i in dct, lst))
现在让我们找到最快的方法,使用 timeit :
Now let's find fastest approach with 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
所以最快的选项是通过if语句在生成器表达式
So the fastest option is to sum items via if statement within generator expression
sum(dct[k] for k in lst if k in dct) # Via sum and condition: 9.4715681076
祝你好运
这篇关于过滤Python生成器表达式中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!