我一直在用 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
两次的值,如果我想要一个 if 函数,我还需要一个。有什么办法可以解决吗?
我一直在用 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
两次的值,如果我想要一个 if 函数,我还需要一个。有什么办法可以解决吗?
如果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())
抵制在这里嵌套生成器表达式的诱惑;是的,它可以做到,但只会使您的代码无法破译。
我不确定解释器如何处理您的代码。
但你可以使用:
max((u for u in (i*j for i in range(100,1000) for j in range(100,1000)) if u%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))))
然而,虽然我相信上面的代码回答了你的问题,但我认为这个解决方案在直觉上并不容易理解——只需给你的中间结果一个名字。