Python基于子列表的一部分删除列表列表中的重复项

时间:2017-05-10 17:25:37

标签: python

我在python中有一个列表,如此

[
  [12,15],
  [13,16],
  [14,17],
  [14,18],
  [14,18],
  [15,19],
  [16,19],
  [17,19],
  [18,20],
]

如何仅基于子列表的第2列从该列表中删除重复项。所以我得到以下内容:

[
  [12,15],
  [13,16],
  [14,17],
  [14,18],

  [15,19],


  [18,20],
]

如果我想让最后一个留在第一个怎么办?像这样:

[
  [12,15],
  [13,16],
  [14,17],

  [14,18],


  [17,19],
  [18,20],
]

因此,根据子列表删除重复项。并选择保留第一个或最后一个。

编辑:

我忘了提及我还需要按顺序保留原始列表(减去重复项)。订购很重要,列表并不总是按计数顺序(12,13,14等,而是随机数字)。

2 个答案:

答案 0 :(得分:2)

您可以使用OrderedDict。按排序值将项目插入字典。连续插入将覆盖以前的值。因此,插入顺序选择是使用找到的第一个还是最后一个重复值。 OrderedDict会记住插入项目的顺序。

from collections import OrderedDict

l = [[12, 15], [13, 16], [14, 17], [14, 18], [14, 18],
     [15, 19], [16, 19], [17, 19], [18, 20]]

use_first_value = OrderedDict((i[1], i) for i in reversed(l))
filtered_list = list(reversed(use_first_value.values()))
print(filtered_list)

use_last_value = OrderedDict((i[1], i) for i in l)
filtered_list = list(use_last_value.values())
print(filtered_list)

更新:将上面的代码重构为支持方向和键功能的常用方法。我不确定Python如何为sorted()这样的函数执行默认的键函数参数,所以我使用了一个返回传递项的lambda。

import operator

def remove_duplicates(items, key=lambda x: x, keep_older=False):
    # iter acts like an identity function here, i.e. no 
    # change to the order and Python would have called it
    # anyway.
    sort_fn = iter if keep_older else reversed
    values = OrderedDict((key(i), i) for i in sort_fn(items)).values()
    return list(sort_fn(values))

# Use a key function to make it more generic
key_fn = operator.itemgetter(1)

# prefer earlier items
remove_duplicates(l, key=key_fn)

# prefer later items
remove_duplicates(l, key=key_fn, keep_older=True)

答案 1 :(得分:1)

使用集合来跟踪重复项,同时将元素复制到新列表中:

seen = set([])
new_list = []
for item in l:
    if item[1] not in seen:
        new_list.append(item)
        seen.add(item[1])

要保留最后一个,只需反向遍历列表

for item in reversed(l):