在python list comprehension中设置变量

时间:2015-02-13 18:11:43

标签: python generator

如果我在每个循环的生成器中完成了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只是让它更容易阅读。 另外,如果有办法,你会如何设置多个变量?

如果以前曾被问过,请道歉,但我已经四处寻找并找不到任何东西。

3 个答案:

答案 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]