在Python中保留列表中的重复项

9

我知道这可能是一个简单的答案,但我想不出来。在Python中保留列表中重复项的最佳方法是什么:

x = [1,2,2,2,3,4,5,6,6,7]

输出应该是:
[2,6]

我找到了这个链接:在Python中查找(并保留)子列表的重复项,但我对Python还比较新手,无法将其应用于简单的列表。


你尝试过那篇帖子中的单行代码吗? - Daniel Casserly
你需要保留顺序吗? - DSM
@DSM -- 看起来我们想的一样... - mgilson
请发布您遇到问题的代码,否则这将是对其他问题的完全重复。 - Steven Rumbalski
不需要保留顺序。 - myname
2
@StevenRumbalski:不完全是,另一个问题还需要同时展开嵌套的列表。 - MattH
5个回答

16

我会使用 collections.Counter

from collections import Counter
x = [1, 2, 2, 2, 3, 4, 5, 6, 6, 7]
counts = Counter(x)
output = [value for value, count in counts.items() if count > 1]

以下是另一个版本,它保留了首次复制物品的顺序,假设传入的序列包含可哈希的项目,并且可以追溯到语言引入setyield的时间(无论那是何时)。

def keep_dupes(iterable):
    seen = set()
    dupes = set()
    for x in iterable:
        if x in seen and x not in dupes:
            yield x
            dupes.add(x)
        else:
            seen.add(x)

print list(keep_dupes([1,2,2,2,3,4,5,6,6,7]))

是的。有很多情况下这不是最佳选择。它还需要输入可哈希...但是,即使对于未排序的列表,它也是O(n),这很好。 - mgilson
1
@DSM — 为什么你需要一个OrderedDict呢?为什么不直接使用[k for k in x if counts[k] > 1]?事实上,这比我之前的方法更好。我会进行更新... - mgilson
@mgilson:试一下就知道了... :^) - DSM
@DSM - 我经常想知道为什么在添加 OrderedDict 时他们没有将 OrderedSet 加入到语言中。在我最近的项目中,我考虑在导入时将其应用于 collections 模块的修补程序...(不过,后来我决定放弃这个想法...) - mgilson
@DSM -- 今天可能不是我最聪明的一天。需要交换seen.add和条件的顺序 - 或者干脆放弃那部分... - mgilson
显示剩余6条评论

10

如果列表已经排序,这是一种简短的方法:

x = [1,2,2,2,3,4,5,6,6,7]

from itertools import groupby
print [key for key,group in groupby(x) if len(list(group)) > 1]

1
这也适用于Python2.6,这是我的问题。 - mgilson
@luchosrock:不,groupby只会将连续的元素分组。 - Jochen Ritzel

2

结合set()使用的列表推导式将完全实现您想要的功能。

list(set([i for i in x if x.count(i) >= 2]))

>>> [2,6]

0

虽然不是很高效,但为了得到输出,你可以尝试:

import numpy as np

def check_for_repeat(check_list):
    repeated_list = []

    for idx in range(len(check_list)):
        elem = check_list[idx]
        check_list[idx] = None

        if elem in temp_list:
            repeated_list.append(elem)

    repeated_list = np.array(repeated_list)

    return list(np.unique(repeated_list))

0

保持简单:

array2 = []
aux = 0
aux2=0
for i in x:
    aux2 = i
    if(aux2==aux):
        array2.append(i)
    aux= i
list(set(array2))

那应该可以工作


那不会得到 [2,2,6] 吗? - DSM
@DSM 哈哈,你说得完全正确,我编辑了我的答案,谢谢 :) - luchosrock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接