如果我在每个循环的生成器中完成了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只是让它更容易阅读。
另外,如果有办法,你会如何设置多个变量?
如果以前曾被问过,请道歉,但我已经四处寻找并找不到任何东西。
答案 0 :(得分:6)
解决昂贵操作的一种方法是将生成器嵌套在列表推导中,该列表解析仅用作过滤器,例如
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]
答案 1 :(得分:3)
正如你正确推测的那样,Python的大多数实现没有共同的子表达式优化,因此你的第一个表达式确实会在每次迭代时调用len(x)两次。那么为什么不只是有两个理解:
a = [len(x) for x in list]
b = [x for x in a if x > 1]
这两次传球,但只有一次len()。如果功能很昂贵,那可能就是胜利。我必须时间确定这一点。
Cyber的嵌套版本基本上是相同的。
答案 2 :(得分:1)
在python2中使用itertools.imap
将是一种有效的方式来做你需要的,并且最有可能胜过生成器表达式:
[x for x in imap(len, lst) if x > 4]