簡體   English   中英

帶有多個'if'的python列表理解

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM