2017-05-10 81 views
-3

的一个部分,我有像这样在名单列表的Python删除重复基于子表

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

如何从只基于子表的第2列列表中删除重复Python的list。因此,我得到以下内容:

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

+4

vhere是你尝试 –

回答

1

您可以使用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) 
+0

这是完美的,现在我已经了解了OrderedDict。非常感谢。即使第二个元素中的重复项不总是彼此相邻,它似乎也可以工作。 – Nertskull

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

对不起,我没有在最初的问题(现在更新)这个不清楚,但将在维持秩序?我认为set()会失去顺序。我需要保持列表的排序(减去重复)。 – Nertskull

+0

是保证从一开始就按顺序排列的第二个元素,即所有副本都是彼此相邻的? – Harvey

+0

@Nertskull元素将按顺序保存。该组仅用于保存先前看到的值。 在“keep last”示例中,顺序将颠倒过来,但可以在for循环之后通过反转来修复:'new_list = reversed(new_list)' – jmhummel