列表理解/生成器中的Walrus赋值表达式



我正试图将foo_list的每个元素传递到函数expensive_call中,并获得expensive_call输出为Truthy的所有项的列表。我正试着用列表综合法来做这件事,有可能吗?类似于:

类似这样的东西:

result_list = [y := expensive_call(x) for x in foo_list if y]

或者。。。。

result_list = [y for x in foo_list if y := expensive_call(x)]

注意:这不是一个解决方案,因为它调用了两次昂贵的调用:

result_list = [expensive_call(x) for x in foo_list if expensive_call(x)]

在有人建议无列表理解之前,我知道有人可以做到:

result_list = []
for x in foo_list:
result = expensive_call(x)
result and result_list.append(result)

以上报价:

result_list=[y for x in foo_list if y:=expensive_call(x(]

它应该与您的工作方式几乎完全一样;只需记住用:=运算符将赋值括起来,如下所示。

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)

结果:

[1, 3]

正如RufusVS所建议的,这是可行的,并且具有预期的复杂性。

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])

中的结果

[True, True]

由于有两个5满足expensive_call

您想检查expensive_call(x)是否为Truthy,如果是,请将其附加到列表中?这样的东西应该行得通。不需要使用海象操作:

[x for x in foo_list if expensive_call(x)]

如果你想存储expensive_call(x)的输出,而不是x,那么由于赋值运算符的工作方式,你的第二种方法需要在walrus赋值周围加括号。有关更多信息,请参阅PEP 572。

[y for x in foo_list if (y := expensive_call(x))]

最新更新