簡體   English   中英

按值從多個列表中刪除發生的元素(縮短多個列表)

[英]Remove occuring elements from multiple lists (shorten multiple lists) by value

說我有一個列表列表:

[[0,0,0,1,2,3],[0,0,0,4,5,6],[0,0,0,0,7,8],[0,0,0,0,0,9]]

我希望最終得到一個列表,該列表將從該列表中的每個列表中刪除常見的null / zero / keyword以產生所需的輸出:

[[1,2,3],[4,5,6],[0,7,8],[0,0,9]]

顯然,循環遍歷該列表中的每個列表,然后將其與所有其他列表進行比較,這是一個理想的答案。 謝謝。

如果您要這些子列表進行排序 ,您會發現最大的子列表將需要從所有這些子列表中刪除的零數。 所以只需找到max

x = [[0,0,0,1,2,3],[0,0,0,4,5,6],[0,0,0,0,7,8],[0,0,0,0,0,9]]

max(x)
Out[2]: [0, 0, 0, 4, 5, 6]

弄清楚你需要丟棄多少個前導零:

from itertools import takewhile

#needlessly pedantic way of doing this
num_zeroes = len(list(takewhile(lambda p: p == 0, max(x))))

並相應切片:

[li[num_zeroes:] for li in x]
Out[12]: [[1, 2, 3], [4, 5, 6], [0, 7, 8], [0, 0, 9]]

顯然,循環遍歷該列表中的每個列表,然后將其與所有其他列表進行比較,這是一個理想的答案。

好吧,沒有辦法將前綴與每個列表的前綴進行比較。

但是您可以避免將每個列表與每個列表進行比較。 換句話說,你可以使這個O(NM),其中M是公共前綴的長度,而不是O(N ** 2)。 只需要兩次傳遞,跟蹤到目前為止在第一次傳球中看到的最長前綴,然后在第二次傳球中使用結果。

或者,我們可以使其更明確,為每個列表計算具有最大值的非零前綴。 很明顯,這是相同數量的步驟(雖然它會以較小的常量變慢,因為它在Python中而不是在C中執行內部循環):

def first_nonzero(seq, stop=None):
    for i, val in enumerate(seq):
        if val or i == stop:
            return i
    return i

prefix = None
for lst in list_o_lists:
    prefix = first_nonzero(lst, prefix)

output = [lst[prefix:] for lst in list_o_lists]

暫無
暫無

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

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