簡體   English   中英

python中的組合filter()無法按預期工作

[英]composed filter() in python doesn't work as expected

據我了解,以下代碼應輸出[['b']] 而是輸出[['a', 'exclude'], ['b']]

這是python中的錯誤,還是我誤會了某些東西?

lists_to_filter = [
    ['a', 'exclude'],
    ['b']
]
# notice that when 'exclude' is the last element, the code returns the expected result
for exclude_label in ['exclude', 'something']:
    lists_to_filter = (labels_list for labels_list in lists_to_filter if exclude_label not in labels_list)
    # notice that changing the line above to the commented line below (i.e. expanding the generator to a list) 
    # will make the code output the expected result, 
    # i.e. the issue is only when using filter on another filter, and not on a list
    # lists_to_filter = [labels_list for labels_list in lists_to_filter if exclude_label not in labels_list]
lists_to_filter = list(lists_to_filter)
print(lists_to_filter)

發生這種情況是因為lists_of_filter僅在循環外部進行迭代。 在循環之外,您具有exclude_label == 'something' ,這就是為什么您得到意外結果的原因。 要檢查它,您可以在一行中添加exclude_label = 'exclude'

lists_to_filter = [
    ['a', 'exclude'],
    ['b']
]

for exclude_label in ['exclude', 'something']:
    lists_to_filter = (labels_list for labels_list in lists_to_filter if exclude_label not in labels_list)

exclude_label = 'exclude'
lists_to_filter = list(lists_to_filter)
print(lists_to_filter)  # [['b']]

生成器表達式文檔說:“ 后續的for子句和最左邊的for子句中的任何過濾條件都不能在封閉范圍內進行評估,因為它們可能取決於從最左邊的iterable獲得的值。 在您的情況下if exclude_label ...的過濾條件取決於for exclude_label in ...循環中從for exclude_label in ...獲得的值。

因為您在循環中多次分配了lists_to_filter ,所以它只會返回最后的結果。 不包括'something'['exclude', 'something']的最后一個元素

您可以使用all來實現您的目標:

lists_to_filter = [labels_list for labels_list in lists_to_filter if all(exclude_label not in labels_list for exclude_label in ['exclude', 'something'])]

或展開all邏輯:

    result = []

    for labels_list in lists_to_filter:
        exclude = False
        for exclude_label in ['exclude', 'something']:
            if exclude_label in labels_list:
                exclude = True
        if not exclude:
            result.append(labels_list)

    print(result)

或者您可以根據標題使用filter

lists_to_filter = list(filter(lambda x: all(exclude_label not in x for exclude_label in exclude_labels), lists_to_filter))

輸出:

[['b']]

希望對您有所幫助,如有其他問題,請發表評論。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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