Python 根据子列表的一部分删除列表列表中的重复项



我在python中有一个这样的列表

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

如何仅根据子列表的第二列从该列表中删除重复项。 这样我就得到了以下内容:

[
  [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等,它将是随机数(。

你可以为此使用 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)

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

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):

最新更新