[英]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
每個成員listy
, for
甚至有英文的。
但是,您可以將循環包裝在一個理解內,或調用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.