簡體   English   中英

刪除列表列表中每個列表中的重復項

[英]Remove duplicates in each list of a list of lists

我有一個列表列表:

a = [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
     [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0],
     [3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 5.0, 5.0, 5.0],
     [1.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0],
     [5.0, 5.0, 5.0], 
     [1.0]
    ]

我需要做的是刪除列表列表中的所有重復項並保留之前的序列。

a = [[1.0],
     [2.0, 3.0, 4.0],
     [3.0, 5.0],
     [1.0, 4.0, 5.0],
     [5.0], 
     [1.0]
    ]

如果順序很重要,您可以與目前看到的項目集進行比較:

a = [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
     [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0],
     [3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 5.0, 5.0, 5.0],
     [1.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0],
     [5.0, 5.0, 5.0], 
     [1.0]]

for index, lst in enumerate(a):
    seen = set()
    a[index] = [i for i in lst if i not in seen and seen.add(i) is None]

這里添加i是為了seen副作用,使用Python的懶惰and求值; seen.add(i)僅在第一次檢查( i not in seen )評估True調用。

歸因:我昨天從@timgeb看到了這種技術

如果您可以訪問 OrderedDict(在 Python 2.7 上),濫用它是一個很好的方法:

import collections
import pprint

a = [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
     [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0],
     [3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 5.0, 5.0, 5.0],
     [1.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0],
     [5.0, 5.0, 5.0], 
     [1.0]
    ]

b = [list(collections.OrderedDict.fromkeys(i)) for i in a]


pprint.pprint(b, width = 40)

輸出:

[[1.0],
 [2.0, 3.0, 4.0],
 [3.0, 5.0],
 [1.0, 4.0, 5.0],
 [5.0],
 [1.0]]

這會幫助你。

a = [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
 [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0],
 [3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 5.0, 5.0, 5.0],
 [1.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0],
 [5.0, 5.0, 5.0], 
 [1.0]
]

for _ in range(len(a)):
    a[_] = sorted(list(set(a[_]))) 

print a

輸出:

[[1.0], [2.0, 3.0, 4.0], [3.0, 5.0], [1.0, 4.0, 5.0], [5.0], [1.0]]

受 DOSHI 的啟發,這是另一種方式,可能是少量可能元素的最佳方式(即排序的少量索引查找),否則記住插入順序的方式可能會更好:

b = [sorted(set(i), key=i.index) for i in a]

所以只是為了比較這些方法,看到的集合與通過原始索引查找對集合進行排序:

>>> setup = 'l = [1,2,3,4,1,2,3,4,1,2,3,4]*100'
>>> timeit.repeat('sorted(set(l), key=l.index)', setup)
[23.231241687943111, 23.302754517266294, 23.29650511717773]
>>> timeit.repeat('seen = set(); [i for i in l if i not in seen and seen.add(i) is None]', setup)
[49.855933579601697, 50.171151882997947, 51.024657420945005]

在這里我們看到,對於更大的情況,Jon 對每個元素使用的包含測試變得相對非常昂貴,並且由於在這種情況下插入順序由索引快速確定,因此這種方法效率更高。

然而,通過在列表的末尾附加更多元素,我們看到 Jon 的方法並沒有增加太多的成本,而我的方法是:

>>> setup = 'l = [1,2,3,4,1,2,3,4,1,2,3,4]*100 + [8,7,6,5]'
>>> timeit.repeat('sorted(set(l), key=l.index)', setup)
[93.221347206941573, 93.013769266020972, 92.64512197257136]
>>> timeit.repeat('seen = set(); [i for i in l if i not in seen and seen.add(i) is None]', setup)
[51.042504915545578, 51.059295348750311, 50.979311841569142]

鑒於索引的查找時間很短,我想我更喜歡 Jon 的帶有可見集合的方法。

暫無
暫無

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

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