2011-10-01 42 views
7

Bir listeye sahibim ve yalnızca belirli bir koşulu yerine getiren girişlerde belirli bir işlevi kullanmak istiyorum - diğer girişler değiştirilmeden bırakılıyor.Python listesi anlaşılır - basit

Örnek: Yalnızca 2 ile çarpmak istediğimi söyle.

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

Aranan sonucu:

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

Ancak [elem * 2 for elem in a_list if elem %2 == 0] verim [4, 8] (bu ek olarak, bir filtre olarak hareket).

Bunun için doğru yol nedir?

cevap

18

kullanın conditional expression:

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

(Matematik müptela not: Ayrıca

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

ile bu özel durumda çözebilir ama ben yine ilk seçeneği tercih ediyorum;)

+0

Teşekkürler, bu harika çalıştı. Ayrıca, düzenlemeler için teşekkürler, sonraki aynı biçimi kullanmaya çalışacağım. –

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

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

veya yerinde değiştirmek istediğiniz çok uzun bir listeniz varsa:

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

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

yüzden, sadece hatta elemanlar

değiştirilir
+0

A_list [:] = list_comprehension' yerinde olmamalıdır? Ve python içinde dönmeye gerek kalmadan? – Voo

+0

@agf Yani yeni listeyi başka bir yerde yaratır ve sonra elemanları günceller mi? Çok kötü, liste anlamaları sınırlamaları nedeniyle, bir öğenin yalnızca üzerine yazılmadan önce referans alınabileceğini garanti edebildiğimizi düşündüğümüzü düşündüm. – Voo

+0

@Voo Yerinde çalışma atama herhangi bir yinelenebilir çalışır, bu yüzden bunu yerine bir jeneratör ifadesinden yapabilirsiniz. Ben sadece denedim, ve aslında 'ters (a_list)' veya listenin uzunluğundan daha az ürün veren bir jeneratör kullansanız bile işe yaramış gibi görünüyor. Daha önce yapmayı düşündüğüm bir şey değil; fikri getirdiğiniz için teşekkürler :). – agf

0

Şunları kullanabilirsiniz lambda:

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

Düzenleme-agf 'görüşüne düşünmek benim kod 2 versiyonu yapılmış:

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

Üçlü işlemi taklit etmek için 'condition ve true_value veya false_value' kullanmayın; Python'da gerçekten bir versiyonu var. Ayrıca, bir lambdaya her iki şekilde de sarılmaya gerek yoktur, çünkü bu, bir liste olarak anlamanın doğru bir ifadesi değil, bir ifadedir. lambda aynı sınırlamalara sahiptir, bu yüzden bir liste anlama veya jeneratör ifadesinde bir ihtiyaç vardır. – agf

+0

@agf - Lambda hakkındaki yorumunuzu anladım (ve katılıyorum), fakat bu durumda bana farklı bir seviyeyi (kesinlikle mükemmel olmaktan uzak olsa da), liste anlamadaki öğeleri seçme mantığını farklı seviyelerde koymak gibi görünüyor. . Ve Python üçlü operatörünün geri kalanı için teşekkür ederim. Bunu yansıtan ikinci bir versiyon yaptım. –

+0

'lambda x:' ve 'f()' 12 karakterdir, [a_list içinde i] 18'dir - bu yüzden ifadeyi "lambda" yerine satır içi olarak göstererek daha net ve hızlı hale getiriyorsunuz Sadece yeni bir işlev yerine tamamen ayrı bir liste kavramanız varsa sadece altı karakter daha. – agf