如何在列表中查找重复项而不创建单独的列表?

时间:2015-08-08 21:42:59

标签: python

如何在不创建任何其他列表的情况下查找列表中的重复项?

实施例

A = [1,2,1,3,4,5,4]

最后

A = [1,4]

5 个答案:

答案 0 :(得分:1)

所以你想要一个函数,它接受列表,A和变异列表,只包含那些最初被复制的元素?我假设创建新列表的限制适用于任何新集合。在询问有关算法的问题时,最好尽可能清楚地了解这些要求。

似乎有一个奇怪的要求,在这个算法中没有其他集合,但它是可能的。 一个简单但效率低下的解决方案就是这样解决:

  • 表示每个元素x
    • 设置布尔标志值,例如hasDuplicatesfalse
    • 代表xy的每个元素
      • 如果yx重复,则将其删除并将hasDuplicates设置为true
    • 如果hasDuplicates为false,请移除x

如果可以放宽不创建另一个集合的限制,或者算法的结果可以是新列表而不是旧的列表,那么您将发现更多(时间)有效的方法。

答案 1 :(得分:1)

我会检查每个元素,如果它出现在它之前但不是之后。如果它不合适,那么它不是重复的,或者是您不想保留的副本的其他出现。无论哪种情况,我们都不保留它。

def simplify(a_list):
    for i in range(len(a_list) - 1, -1, -1):
        value = a_list[i]
        if not value in a_list[:i] or value in a_list[i+1:]:
            del a_list[i]

不确定使用切片是否符合您的要求。

用法:

>>> A = [1,2,1,3,4,5,4]
>>> simplify(A)
>>> A
[1, 4]
>>> A = [1,1,1,1,1,2,2,2,2]
>>> simplify(A)
>>> A
[1, 2]
>>> A = [1,1,1,1,1]
>>> simplify(A)
>>> A
[1]
>>> A = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> simplify(A)
>>> A
[]

答案 2 :(得分:0)

您可以使用set仅获取唯一值,然后从原始列表中逐个删除它们,以便只保留重复项:

a = [1,2,1,3,4,5,4]
s = list(set(a))
for x in s:
    a.remove(x)
print a # [1, 4]

另一个优雅的选择,我偷了'来自Ritesh Kumar的是:
仅收集出现多次的项目,使用set删除重复项,并使用list将其换行以返回列表:

a = [1,2,1,3,4,5,4]
print list(set([x for x in a if a.count(x) > 1])) # [1, 4]

答案 3 :(得分:0)

这应该做你需要的,除非澄清:

def find_duplicated_items(data):
    seen = set()
    duplicated = set()

    for x in data:
        if x in seen:
            duplicated.add(x)
        else:
            seen.add(x)

    return duplicated

它需要一个可迭代的并返回一个集合;您可以将其转换为list(results)的列表。

<强>更新

这是另一种做法,作为发电机。仅仅因为:)。

from collections import Counter

def find_duplicated(iterable, atleast=2):
    counter = Counter()
    yielded = set()

    for item in iterable:
        counter[item] += 1
        if (counter[item] >= atleast) and (item not in yielded):
            yield item
            yielded.add(item)

答案 4 :(得分:0)

此代码似乎删除了第二个重复项和非重复项,从而产生仅包含唯一重复项的旧列表。我还没有彻底测试过它。请注意,所需时间将缩放为O(N ** 2),其中N是输入列表的长度。

与其他解决方案不同,此处没有构建新列表,甚至没有for循环或列表理解的列表。

文件:&#34; dup.py&#34;

def dups(mylist):
    idx = 0 
    while(idx<len(mylist)):
        delidx = idx+1
        ndeleted = 0
        while delidx < len(mylist):
            if mylist[delidx] == mylist[idx]:
                del mylist[delidx]
                ndeleted += 1
            else:
                delidx += 1
        if ndeleted==0:
            del mylist[idx]
        else:
            idx += 1
    return mylist

用法(iPython)

In [1]: from dup import dups

In [2]: dups([1,1,1,1,1])
Out[2]: [1]

In [3]: dups([1,1,2,1,1])
Out[3]: [1]

In [4]: dups([1,1,2,2,1])
Out[4]: [1, 2]

In [5]: dups([1,1,2,1,2])
Out[5]: [1, 2]

In [6]: dups([1,2,3,1,2])
Out[6]: [1, 2]

In [7]: dups([1,2,1,3,4,5,4])
Out[7]: [1, 4]