私たちは皆、パイソンを知っています
[f(x) for x in y if g(x)]
構文。
ただし、リスト内包表記の AST表現には、複数の「if」式を入れる余地があります。
comprehension = (expr target, expr iter, expr* ifs)
複数の 'if' 式を持つ AST を生成する Python コードの例を誰か教えてもらえますか?
私たちは皆、パイソンを知っています
[f(x) for x in y if g(x)]
構文。
ただし、リスト内包表記の AST表現には、複数の「if」式を入れる余地があります。
comprehension = (expr target, expr iter, expr* ifs)
複数の 'if' 式を持つ AST を生成する Python コードの例を誰か教えてもらえますか?
それらを次々に積み重ねるだけです:
[i for i in range(100) if i > 10 if i < 50]
11 から 49 までの整数を生成します。
文法では、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')]
言語リファレンスは、これについてより良いアイデアを提供します:
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 条件を単独でチェーンする可能性は必要ありませんが、文法全体をそのように定義することができます。