Walrus assignment expression in list comprehension/generator
I am trying to pass each element of foo_list
into a function expensive_call
, and get a list of all the items whose output of expensive_call
is Truthy. I am trying to do it with list comprehensions, is it possible? Something like:
Something like this:
result_list = [y := expensive_call(x) for x in foo_list if y]
or....
result_list = [y for x in foo_list if y := expensive_call(x)]
Note: This is not a solution because it call expensive call twice:
result_list = [expensive_call(x) for x in foo_list if expensive_call(x)]
And before someone recommends none list comprehension, I know one can do:
result_list = []
for x in foo_list:
result = expensive_call(x)
result and result_list.append(result)
Solution 1:
Quoting from above:
result_list = [y for x in foo_list if y := expensive_call(x)]
It should work almost exactly as how you have it; just remember to parenthesize the assignment with the :=
operator, as shown below.
foo_list = [1, 2, 3]
def check(x): return x if x != 2 else None
result_list = [y for x in foo_list if (y := check(x))]
print(result_list)
Result:
[1, 3]
Solution 2:
As suggested by RufusVS, this works and has the expected complexity.
def expensive_call(x):
return x == 5
foo_list = [1,2,3,4,5,6,6,5]
print([y for y in map(expensive_call,foo_list) if y])
results in
[True, True]
As there are two 5 that satisfy expensive_call