55

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

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

構文。

ただし、リスト内包表記の AST表現には、複数の「if」式を入れる余地があります。

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

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

4

4 に答える 4

90

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

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

11 から 49 までの整数を生成します。

于 2013-03-06T13:13:35.473 に答える
66

文法では、for ループ間でそれらを混在させることができるため、複数の 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 がステートメントのネストを禁止していないように、文法とパーサーはそのような使用法を明確に禁止していません。if

PEP 202 – List Comprehensions (この機能を言語に追加した元の提案文書) には、実際には例のセクションに double-if 内包表記が含まれていることに注意してください。

>>> 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')]
于 2013-03-06T13:16:37.057 に答える
7

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

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 部分または if 条件のいずれかになります。if 条件自体は、別のオプションの で終了しますlist_iter。これは、同じリスト内包表記でオプションの if 条件を使用して複数の for パーツを連鎖できるようにするために不可欠です。.. if X if Y if Zのパーツも作成できるという事実list_iterは、単なる副作用です。

そのため、複数の if 条件を単独でチェーンする可能性は必要ありませんが、文法全体をそのように定義することができます。

于 2013-03-06T13:22:43.300 に答える