Filter value inside Python generator expressions

I have a dictionary dctfor which I want its each value to be summed if the corresponding keys exist in the specified list lst.

The code I use so far is:

sum(dct[k] for k in lst)

In the above generator expression, I would like to process KeyErrorif the key from the list is not found inside the dictionary. I can't seem to find how to implement the (syntactic) approach either try- exceptnor the approach if- elsein this generator expression.

If the key from the list is not found inside the dictionary, it should continue to receive other values. The final results of the amounts should not be affected by the missing keys. If none of the keys exists, then zero should be the result of the sum.

+4
source share
5 answers

Well, there are several options, it is preferable 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)

Also one of the options is filtering lstbefore repeating it:

sum(dct[k] for k in filter(lambda i: i in dct, lst))

And you can use the reduce function in the filtered list as an alternative sum:

reduce(lambda a, k: a + dct[k], filter(lambda i: i in dct, lst))

Now find a quick 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

Thus, the fastest option is to sum the elements through the if statement in the generator expression

sum(dct[k] for k in lst if k in dct) # Via sum and condition: 9.4715681076

Luck!

+1
source

You have two options:

Check for key availability

sum(dct[k] for k in lst if k in dct)

or using get

sum(dct.get(k, 0) for k in lst)

dct.get(k, 0) dct[k], k dct 0, .

+5

You can simply use .get()to try to get the value for the key from the dictionary, and if it is not found, it will return None, or your provided default parameter, which in this case will be 0.

>>> dct = {1:2, 3:4, 5:6}
>>> lst = [1,5]
>>> sum(dct.get(k, 0) for k in lst)
8    

If some (or all) of the keys do not exist, the amount will still function properly.

>>> lst = [10, 11]
>>> sum(dct.get(k, 0) for k in lst)
0
+2
source
sum(dct[k] for k in lst if k in dct)
+1
source

You can use the get-dictionaries method to provide a default value if not found:

sum(dct.get(k, 0) for k in lst)
+1
source

All Articles