在 python 列表理解中设置变量

Set variables in python list comprehension

如果我在每个循环的生成器中完成了 2 或 3 个相同的计算,有没有办法将它们设置为变量?

一个简单的例子是这样的:

#Normal
[len( i ) for i in list if len( i ) > 1]

#Set variable
[x for i in list if x > 1; x = len( i )]

在有人说 len( i ) 如此之快之前,差异可以忽略不计,我的意思是对于其他计算,使用 len 只是让它更容易阅读。 另外,如果有办法,你会如何设置多个变量?

抱歉,如果之前有人问过这个问题,但我四处搜索但没有找到任何东西。

避免昂贵操作的一种方法是将生成器嵌套在列表理解中,该列表理解仅充当过滤器,例如

def foo(x):       # assume this function is expensive
    return 2*x

>>> [j for j in (foo(i) for i in range(6)) if j > 4]
#                ^ only called once per element
[6, 8, 10]

对您的示例使用类似的函数和变量,您将有

[x for x in (len(i) for i in list) if x > 1]

在 python2 中使用 itertools.imap 将是一种满足您需要的有效方式,并且很可能优于生成器表达式:

[x for x in  imap(len, lst) if x > 4]

大多数 Python 的实现并不像您正确推测的那样具有公共子表达式优化,因此您的第一个表达式确实会在每次迭代中调用 len(x) 两次。那么为什么不只有两个理解:

a = [len(x) for x in list]
b = [x for x in a if x > 1]

这进行了两次传递,但每次只调用一次 len()。如果这个功能是一个昂贵的功能,那可能是一个胜利。我必须确定时间。

Cyber​​ 的嵌套版本本质上是一样的。