簡體   English   中英

如何通過子列表項子集在Python列表列表中刪除重復項?

[英]How to remove duplicates, by sublist item subset, in a list of lists in Python?

我在Python中有一個定義如下的列表: [[2, 3, 5], [3, 3, 1], [2, 3, 8]] ,我不想刪除重復的條目,但是用重復表示,我的意思是每個列表的前兩個元素都匹配,例如,第一個和第三個列表的第一個和第二個元素具有2和3,因此,我將其視為重復,刪除后我希望具有最終列表: [[2, 3, 5], [3, 3, 1]] 目前,我有這樣的事情:

arr = [[2, 3, 5], [3, 3, 1], [2, 3, 8]]

first = [item[0] for item in arr]
second = [item[1] for item in arr]
zipped = zip(first, second)

這將生成元組列表,其中每個列表的前兩個條目都是如此。 現在,我可以嘗試獲取重復條目的索引,並將這些索引從原始列表中刪除。 但是,有沒有更短的方式來做我想要的事情? 如果不是,在這里獲取重復索引的最佳方法是什么?

您可以使用集合來完成此任務:

arr = [[2, 3, 5], [3, 3, 1], [2, 3, 8]]

used = set()
[used.add(tuple(x[:2])) or x for x in arr if tuple(x[:2]) not in used]

退貨

[[2, 3, 5], [3, 3, 1]]

筆記

  1. 僅當未used任何子列表的前兩個元素時才評估第一個表達式。 查看清單推導中的文檔以獲取更多信息。
  2. 知道set.add總是返回None 因此used.add(tuple(x[:2])) or x總是計算為x
  3. 由於list不可散列,因此我們需要將子列表的前兩個元素轉換為不可變的(例如元組)。

最后,如果您不熟悉這種模式,就會出現@wim,這可能很難理解,並且在Python中“可讀性很重要”。 因此,如果您要編寫將共享的代碼,請考慮將其更改為顯式的for循環或使用其他方法。

您可以將collections.OrderedDict用於保留訂單的重復數據刪除:

>>> d = OrderedDict(((x[0], x[1]), x) for x in reversed(L))
>>> print(*d.values())
[2, 3, 5] [3, 3, 1]

要保留最后一個而不是第一個,只需刪除reversed

>>> OrderedDict(((x[0], x[1]), x) for x in L).values()
odict_values([[2, 3, 8], [3, 3, 1]])

或使用簡單的舊for循環:

def dedupe(iterable):
    seen = set()
    for x in iterable:
        first, second, *rest = x
        if (first, second) not in seen:
            seen.add((first, second))
            yield x

暫無
暫無

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

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