【发布时间】:2012-07-21 10:27:02
【问题描述】:
考虑以下列表理解
[ (x,f(x)) for x in iterable if f(x) ]
这会根据条件 f 过滤可迭代对象,并返回成对的 x,f(x)。这种方法的问题是f(x) 被计算了两次。
如果我们能像这样写就太好了
[ (x,fx) for x in iterable if fx where fx = f(x) ]
or
[ (x,fx) for x in iterable if fx with f(x) as fx ]
但在 python 中,我们必须使用嵌套推导式来编写,以避免重复调用 f(x),这使得推导式看起来不太清晰
[ (x,fx) for x,fx in ( (y,f(y) for y in iterable ) if fx ]
有没有其他方法可以让它更具 Python 风格和可读性?
更新
即将在 python 3.8 中推出! PEP
# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y := f(x)) is not None]
【问题讨论】:
-
你确定编译的时候会计算两次吗?
-
不确定如何编译。但是在 python 提示符下,它被执行了两次。我通过添加打印语句进行检查。
-
如果不想计算
f(x)两次,请尝试在f()中添加缓存。 -
@Vixen:是的,python 将在第一条语句中为每个
x in iterable调用两次f(x)。 -
这与其说是“
[... where ...]子句”,不如说是想优化[... if ...]子句和/或引入let样式的匿名绑定。
标签: python python-3.x list-comprehension python-assignment-expression python-3.8