2011-10-01 8 views
7

私はリストを持っていますが、特定の条件を満たすエントリだけに特定の機能を使いたいのです。他のエントリは変更しないでください。Python list comprehension - simple

例:偶数の要素だけを2で掛けたいとします。

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'sには同じ制限がありますので、リストの理解やジェネレータの表現には必要ありません。 – agf

+0

@agf - 私はラムダについてのあなたのコメントを理解していますが、このケースではリストの理解から項目を選択するロジックを別のレベルに置くための代替方法(完全に完璧ではありませんが) 。 そしてPythonの三項演算子については残念です。私はこれを反映するために第2版を作った。 –

+0

'lambda x:'と 'f()'は12文字ですが、 '[for i in a_list]'は18ですので、 'lambda'ではなく、インラインで表現することで、あなたが新しい機能の代わりに完全に別のリストの理解力を持っているならば、わずか6文字です。 – agf

関連する問題