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

Python基于子列表的一部分删除列表列表中的重复项,python,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], ] 如果我想保留最后一个而不是第一个呢?像这样

我有一个类似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等,而是随机数)。

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

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

您可以使用OrderedICT进行此操作。按排序后的值将项目插入字典。连续插入将覆盖以前的值。因此,插入顺序选择使用找到的第一个或最后一个重复值。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)

V这是您的尝试对不起,我在最初的问题(现在更新)中没有说明这一点,但这会保留订单吗?我以为set()会失去秩序。我需要保持列表的顺序(减去重复项)。是否保证第二个元素从一开始就是有序的,即所有重复项彼此相邻?@Nertskull元素将按顺序保留。该集合仅用于保存前面看到的值。在“keep last”示例中,顺序将被反转,但您可以通过在for循环之后反转它来解决这一问题:
new\u list=reversed(new\u list)
这很完美,我现在已经了解了OrderedDict。非常感谢你。即使在第二个元素中的重复项并不总是彼此相邻的情况下,它似乎也能工作。