我在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等,而是随机数字)。
答案 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):