2013-03-20 90 views
2

我一直插科打諢與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,如果我想要一個更多的功能,我還需要一個。有什麼方法可以解決它嗎?

+1

你也可以通過刪除''''''括號來增加內存的效率,所以max函數在生成時會消耗這些值,而不是消耗全部的值,然後從列表中消耗max函數正在記憶中。 – GP89 2013-03-20 13:03:46

回答

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()) 

抵制誘惑,在這裏築巢生成器表達式;是的,它可以完成,但僅用於使您的代碼無法解讀。

0

我不確定解釋器如何處理您的代碼。

但是你可以使用:

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

在這種情況下,我認爲它更好地使用發電機()而不是使用列表[],因爲你並不需要的所有數據,只最大的一個。

+0

好的,但我的問題實際上是否可以使用臨時名稱。示例代碼僅用於指出可能的用例。所以問題依然... – user2190798 2013-03-20 14:11:17

0

一般來說,Python的哲學非常符合以下的說法:如果你想重新使用一些中間結果,然後給它一個名字。在習慣上,_用於建議臨時名稱。另外,如果列表理解或生成器表達式跨越兩行或更多行,則最好使用明確的for-loop重寫它。也就是說,有人可能會(錯誤地)使用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)))) 

不過,雖然我相信上面的代碼回答你的問題,我不認爲這個解決方案是直觀理解的 - 只是給你的中間結果的名稱。

相關問題