过滤生成器表达式输出的pythonic/惯用方法是什么?

假设我们有一个生成器表达式,也许是一个简单的表达式,但不一定如此:

(function(x) for x in values)

过滤此生成器表达式生成的值的首选方法是什么?即我们不想过滤 的值x,而是过滤function(x)?

当然

# this only filters on the inputs to the function, not on its results
(function(x) for x in values if _some_condition_expr_) 

我认为以下内容是最pythonic的(顺便说一句,也摆脱了生成器表达式本身):

_ = lambda x: x  # simple filter for truthy values

filter(_, map(function, values))           # <<< is this the best we can do?
# or
filter(_, (generator_expression_contents_here))

- 与这种憎恶相反:

(y for y in (function(x) for x in values) if y)

我在生成器表达式中是否缺少一些允许过滤结果而不嵌套表达式等的东西?换句话说,这种filter(map())方法是我们能做的最好的吗?我不是要寻找深奥的东西,只是确保我没有遗漏一些更简洁或更 Pythonic 的方法。

AFAIK,Python 没有身份函数(_上面),也没有is_true函数。

回答

关于这是否更好,这是一个有争议的问题,但:=可以在这里使用:

filtered = (res for val in values if (res := function(val)))

函数的结果被赋值给res,该结果被用作谓词,然后res可以在左边使用。


回答

这是为赋值表达式提出的用例之一:

>>> def f(x):
...     return x % 3
... 
>>> g = (fx for x in range(10) if (fx := f(x)))
>>> list(g)
[1, 2, 1, 2, 1, 2]

改编自PEP 572 中的简化列表理解

如果您在支持赋值表达式之前使用 Python 版本,或者您只是发现它们很丑,那么链接生成器就可以了:

>>> g1 = (f(x) for x in range(10))
>>> g2 = (x for x in g1 if x)
>>> list(g2)
[1, 2, 1, 2, 1, 2]

请注意,通过 using而不是 callable直接支持对真值进行简单过滤None

>>> list(filter(None, range(3)))
[1, 2]

所以你可以使用filter(None, map(f, vals))类似的效果。


以上是过滤生成器表达式输出的pythonic/惯用方法是什么?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>