2011-10-01 128 views
7

我有一個列表,我希望只對那些符合某些條件的條目使用某個函數 - 使其他條目保持不變。Python列表理解 - 簡單

例如:假設我想只乘以那些偶數的元素。

a_list = [1, 2, 3, 4, 5] 

求購結果:

a_list => [1, 4, 3, 8, 5] 

但是[elem * 2 for elem in a_list if elem %2 == 0]收率[4, 8](它充當另外的過濾器)。

什麼是正確的方式去呢?

回答

18

使用conditional expression

[x * 2 if x % 2 == 0 else x 
for x in a_list] 

(數學怪才注:您還可以解決這種特殊情況下與

[x * (2 - x % 2) for x in a_list] 

但我想反正喜歡的第一個選項;)

+0

謝謝,這個工作很好。 另外,感謝您的編輯,我會嘗試使用下一個相同的格式。 –

2
a_list = [1, 2, 3, 4, 5] 

print [elem*2 if elem%2==0 else elem for elem in a_list ] 

或者,如果您有很長的列表要修改:

a_list = [1, 2, 3, 4, 5] 

for i,elem in enumerate(a_list): 
    if elem%2==0: 
     a_list[i] = elem*2 

所以,只有偶數元素被修改

+0

不應該''a_list [:] = list_comprehension'也適用於就地更換嗎?而且不需要在Python中循環? – Voo

+0

@agf因此它會在其他地方創建新列表,然後更新元素?太糟糕了,我認爲由於列表解析的侷限性,我們可以保證一個元素只能在被覆蓋之前被引用,以便可以進行優化。 – Voo

+0

@Voo就地分配可以從任何迭代中進行,因此您可以通過生成器表達式來完成。我剛剛嘗試過,而且即使使用'reversed(a_list)'或一個產生比列表長度更少的項的生成器,它似乎也能工作。不是我以前想過的事情;感謝提出這個想法:)。 – agf

0

你可以使用拉姆達:

>>> a_list = [1, 2, 3, 4, 5] 
>>> f = lambda x: x%2 and x or x*2 
>>> a_list = [f(i) for i in a_list] 
>>> a_list 
[1, 4, 3, 8, 5] 

編輯 - 約agf此言思考我做了我的代碼第2個版本:

>>> a_list = [1, 2, 3, 4, 5] 
>>> f = lambda x: x if x%2 else x*2 
>>> a_list = [f(i) for i in a_list] 
>>> a_list 
[1, 4, 3, 8, 5] 
+0

不要使用'condition和true_value或false_value'來模擬三元操作; Python中有一個真正的版本。而且,不需要用lambda包裝它,因爲它是一個表達式而不是語句,它在列表理解中正常工作。 lambda具有相同的限制,因此在列表理解或生成器表達式中不需要一個。 – agf

+0

@agf - 我理解(並同意)你對lambda的評論,但在這種情況下,在我看來,另一種方式(儘管遠非絕對完美)將不同級別的選擇項目從列表理解中選擇的邏輯。 並感謝您關於Python三元運算符的其餘部分。我做了第二個版本來反映這一點。 –

+0

'lambda x:'和'f()'是12個字符,'[對於i中的a_list]'是18 - 所以你通過內聯表達式而不是'lambda'來使它更加清晰和快速只有六個字符,如果你有一個單獨的列表理解,而不是一個新的功能。 – agf