[英]python list comprehension with multiple 'if's
我們都知道python的
[f(x) for x in y if g(x)]
句法。
但是,列表理解的AST表示可以容納多個“ if”表達式:
comprehension = (expr target, expr iter, expr* ifs)
有人可以給我一個python代碼示例,該示例會生成帶有多個“ if”表達式的AST嗎?
語法允許使用多個if語句,因為您可以在for循環之間混合使用它們:
[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 – 列表理解 (在語言中添加了此功能的原始提案文檔)實際上在示例部分中包含了雙重理解:
>>> 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')]
只需將它們一個接一個地堆疊:
[i for i in range(100) if i > 10 if i < 50]
產生介於11和49之間(含)的整數。
使用內置的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)])]
如果只需要滿足一個條件,則內置的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]
語言參考對此提供了一個更好的主意:
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
可以是列表理解的另一部分,也可以是if條件。 如果條件本身再次以另一個可選的list_iter
結尾。 這對於在同一列表理解中使用可選的if條件鏈接多個for-parts至關重要。 您也可以構造一個.. if X if Y if Z
list_iter
.. if X if Y if Z
部分的事實只是一個副作用。
因此,雖然不需要單獨鏈接多個if條件的可能性,但它允許以這種方式定義整個語法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.