web-dev-qa-db-ja.com

python複数の 'if'を含むリスト内包表記

私たちは皆パイソンのものを知っています

[f(x) for x in y if g(x)]

構文。

ただし、リスト内包表記の [〜#〜] ast [〜#〜] 表現には、複数の 'if'式の余地があります。

comprehension = (expr target, expr iter, expr* ifs)

誰かがpython複数の 'if'式でASTを生成するコードの例を教えてもらえますか?

34
Stefan

それらを次々に積み重ねるだけです:

[i for i in range(100) if i > 10 if i < 50]

11〜49の整数を生成します。

47
Emil Vikström

文法では、forループ間で複数のifステートメントを混在させることができるため、複数のifステートメントを使用できます。

[j for i in range(100) if i > 10 for j in range(i) if j < 20]

理解コンポーネントは、ネストされたステートメントと見なされる必要があります。上記は次のように変換されます。

lst = []
for i in range(100):
    if i > 10:
        for j in range(i):
            if j < 20:
                lst.append(j)

これは、間にifループなしで複数のforステートメントを使用できることも意味します。

[i for i in range(100) if i > 10 if i < 20]

意味がありませんが(andを使用するか、チェーン演算子を使用するだけで結合できます)、それでも正しいネストされたステートメントのセットに変換されます:

lst = []
for i in range(100):
    if i > 10:
        if i < 20:
            lst.append(i)

文法とパーサーは、Pythonがあなたを禁止しないのと同じように、そのような使用法を特にdisallowifステートメントをネストします。

PEP 202 –List Comprehensions (この機能を言語に追加した元の提案文書)には実際に二重の例のセクションで理解する場合:

>>> print [(i, f) for i in nums for f in fruit if f[0] == "P" if i%2 == 1]
[(1, 'Peaches'), (1, 'Pears'), (3, 'Peaches'), (3, 'Pears')]
49
Martijn Pieters

組み込みのall()を使用すると、複数のブール式または関数を反復可能に配置し、理解に固執することができます。私はそれがかなり使い古されたビルトインであり、読みやすさを高く保つと思います。

_>>> [x for x in range(20) if all([1 < x < 10, not x & 1])]
[2, 4, 6, 8]
_

または

_>>> [x for x in range(20) if all([foo(x), bar(x)])]
_

満たされる必要がある条件が1つだけの場合、組み込みのany()もうまく機能します。

_>>> [x for x in range(20) if any([1 < x < 10, not x & 1])]
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18]
_
12
kylie.a

言語リファレンス は、これに関するより良いアイデアを提供します:

list_comprehension  ::=  expression list_for
list_for            ::=  "for" target_list "in" old_expression_list [list_iter]
list_iter           ::=  list_for | list_if
list_if             ::=  "if" old_expression [list_iter]

ご覧のように、リストの内包表記は、オプションのlist_iterで定義されています-単一のlist_iterです。これで、このlist_iterはリスト内包表記の別のfor-partまたはif-conditionのいずれかになります。 if条件自体は、別のオプションのlist_iterで再び終了します。これは、同じリスト内包内のオプションのif条件で複数のfor-partsを連鎖できるようにするために不可欠です。 .. if X if Y if Zlist_iter部分も作成できるという事実は、単なる副作用です。

したがって、複数のif条件を単独で連鎖させる可能性は必要ありませんが、文法全体をそのように定義できます。

5
poke