1行リスト内包表記:if-elseバリアント


178

それはpythonリスト内包構文に関するものです。特定の範囲の奇数のリストを生成するリスト内包を持っています。

[x for x in range(1, 10) if x % 2]

これによりフィルターが作成されます-ソースリストがあり、偶数(if x % 2)を削除しています。ここではif-then-elseのようなものを使用したいと思います。次のコードは失敗します:

>>> [x for x in range(1, 10) if x % 2 else x * 100]
  File "<stdin>", line 1
    [x for x in range(1, 10) if x % 2 else x * 100]
                                         ^
SyntaxError: invalid syntax

if-elseのようなpython式があります。

1 if 0 is 0 else 3

リスト内包表記の中でそれを使用するには?


1
価値のあることですが、ジェネレータではなく「リスト内包」があります。ジェネレーターがの()代わりに使用する以外は、最終的な構文は同じです[]
mgilson 2013年


2
なぜ偶数をif x % 2 削除するのか(それらを保持するのではなく)を取得するのにしばらく時間がかかりました。これはxx % 2式が0になり、がに評価されFalse、がに評価され、それint以外はがに0評価されるためTrueです。

回答:


328

x if y else z各要素に対して返す式の構文です。したがって、次のものが必要です。

[ x if x%2 else x*100 for x in range(1, 10) ]

混乱は、最初の例ではフィルターを使用しているが、2番目の例では使用していないために発生します。2番目の例では、3項演算子式を使用して、各値を別の値にマッピングするだけです。

フィルターには、次のものが必要です。

[ EXP for x in seq if COND ]

フィルターなしで必要なもの:

[ EXP for x in seq ]

2番目の例では、式は「複雑な」式で、たまたまが含まれますif-else


2
質問が1つあります... [x for x in range(1, 10) if x % 2]正しい構文です。[x if x % 2 for x in range(1, 10)]-これは[x if x%2 else x*100 for x in range(1, 10)]正しい構文ではありませんが、正しい構文です。どうして?
ducin 2013年

2番目の例の@tkoomzaaskzでは、これはternary-if-else演算子(がないelse)でもフィルターでもありません(EXPリスト内包表記の一部であるため)
shx2

3
@tkoomzaaskzさらに明確にするために、if最後に2番目を追加できることに注意してください[x if x%2 else x*100 for x in range(1, 10) if not x%3]。最初ifは3項演算子のif一部で、2番目はリスト内包構文の一部です。全体x if x%2 else x*100は単純なと同じレベルにあり、のフィルタリングがすでに行われている場合、の2*x左側で評価する式です。forif not x%3
zx81、2015

こんにちは、1行のステートメントfor i in x:は、forループのように2行で作成するよりもパフォーマンスが高くなりますif i == y:か?
Alexis.Rolland


12

リスト内包表記でもこれを行うことができます。

A=[[x*100, x][x % 2 != 0] for x in range(1,11)]
print A

1
非常に素晴らしい。ブールスライス。ありがとう、私にもっと読みやすい解決策を教えてくれました。

次のように二重割り当てすることもできます:A、B = [10,11] [a == 19]、[1,14] [a == 20]
Stefan Gruenwald

10

ちょうど別の解決策、誰かがそれを好きになることを願っています:

使用法:[False、True] [Expression]

>>> map(lambda x: [x*100, x][x % 2 != 0], range(1,10))
[1, 200, 3, 400, 5, 600, 7, 800, 9]
>>>

3

私はこれを行うことができました

>>> [x if x % 2 != 0 else x * 100 for x in range(1,10)]
    [1, 200, 3, 400, 5, 600, 7, 800, 9]
>>>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.