簡體   English   中英

如何過濾列表中的列表?

[英]How to filter lists in a list?

我有例如listy = [[1,-1,2],[3,-2,-4]]

我想過濾,以便只得到正面元素[[1,2 ,, 3]

使用循環和過濾器(lambda x:x> 0,listy)很容易做到這一點,但我想避免循環。

列表推導可以嵌套:

In [2]: [ [i for i in x if i>0] for x in listy ]
Out[2]: [[1, 2], [3]]

關於filter理解和列表理解之間的選擇,BDFL的Guido van Rossum寫道 ,列表理解既清晰又快速。

filter(P,S)幾乎總是寫為[如果P(x)中S中的x為x,x則更清楚),這具有巨大的優勢,即最常見的用法是比較謂詞,例如x == 42,並定義一個lambda只是需要讀者付出更多的努力(加上lambda比列表理解要慢)。

高級主題:處理大型數據集

如果listy很大並且您的應用程序允許,則可能要使用生成器來代替列表:

g = ( (i for i in x if i>0) for x in listy )

您的問題本質上需要循環。 您想為listy每個成員listyfor甚至有英文的。

但是,您可以將循環包裝在一個理解內,或調用map等。例如:

listy = map(lambda sublist: filter(lambda x: x>0, sublist), listy)
listy = [[x for x in sublist if x>0] for sublist in listy]

(或者,當然是上述的其他兩種組合,即關於filter的理解,或對comprehension的map 。)

您還可以懶惰地進行循環,因此您不必浪費時間來預先創建過濾列表,而只需創建迭代器即可按需生成正值:

itery = itertools.imap(lambda sublist: itertools.ifilter(lambda x: x>0, sublist), listy)
itery = ((x for x in sublist if x>0) for sublist in listy)

但這僅意味着循環發生在以后,當您遍歷itery每個元素時,而不是立即進行。

(同樣,您可以將以上兩個想法結合起來,例如,一個迭代器列表或一個列表迭代器,而不是一個迭代器或一個列表列表。)

您甚至可以通過創建Python列表的一維數組並在其上調用vectorize(lambda lst: filter(lambda x: x>0, sublist))在NumPy元素操作內隱藏循環。 但是循環仍然存在。


當然,您也可以通過間接循環繞過循環。 例如,使用遞歸:

def filter_nonpositives(x):
    return x[:x[0]>0] + filter_nonpositives(x[1:])

或者甚至通過將循環展開到最大大小來實現:

def filter_nonpositives(x):
    result = []
    if len(x) == 0:
        return result
    if x[0] > 0:
        result.append(x[0])
    if len(x) == 1:
        return result
    if x[1] > 0:
        result.append(x[1])
    if len(x) == 2:
        return result
    if x[2] > 0:
        result.append(x[2])
    # ... repeat as far as you want
    return result

但是,無論哪種方式,您仍然可以有效地循環執行-很難找到任何人認為Python或更高級。

暫無
暫無

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

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