list-comprehension中的临时名称

时间:2013-03-20 12:30:36

标签: python python-3.x list-comprehension

我一直在使用python列表理解进行一些处理,并创建了这个单行计算器来计算作为两个三位数字的乘积而产生的最大偶数:

max([ i*j for i in range(100,1000) for i in range(100,1000) if i*j%2== 0 ]) 

问题如下:有没有办法避免重新计算i * j的值,比如为它分配临时名称并使用它?

让我感到困惑的是,我计算了i*j两次的值,如果我想要一个更多功能,我还需要一个。有没有办法解决它?

3 个答案:

答案 0 :(得分:3)

如果i*j很贵,请使用生成器函数:

def values():
    for i in range(100, 1000):
        for j in range(100, 1000):
            ij = i * j
            if ij % 2 == 0:
                yield ij

max(values())

在这里抵制嵌套生成器表达式的诱惑;是的,它可以完成,但只能使你的代码难以理解。

答案 1 :(得分:0)

我不确定口译员如何处理您的代码。

但你可以使用:

max((u for u in (i*j for i in range(100,1000) for j in range(100,1000)) if u%2== 0))

在这种情况下,我认为最好使用generator()而不是使用list [],因为你不需要所有数据,只需要最大数据。

答案 2 :(得分:0)

一般来说,Python的哲学非常符合:如果你想重用一些中间结果,那就给它一个名字。惯用法,_用于建议临时名称。此外,如果列表推导或生成器表达式跨越两行或更多行,则最好使用显式for循环重写它。

也就是说,人们可能(误)使用Python的功能来编写代码,而不需要任何中间名。几乎就是这样:因为我们不能使用functools.partial来固定非最左边和非关键字的参数,所以我们必须自己构建mod2函数,而不是使用partial

from itertools import iterfalse, product, starmap
from operator import mod, mul
mod2 = lambda x: mod(x, 2) # this would be nicer with functools.partial
max(filterfalse(mod2, starmap(mul, product(range(100, 1000), repeat=2))))

然而,虽然我确实认为上面的代码回答了你的问题,但我不认为这个解决方案是直观易懂的 - 只需给你的中间结果起一个名字。