如何在整数列表中找到重复项并创建重复项的另一个列表?


当前回答

方法1:

list(set([val for idx, val in enumerate(input_list) if val in input_list[idx+1:]]))

解释: [val for idx, val in enumerate(input_list) if val in input_list[idx+1:]]是一个列表推导式,它返回一个元素,如果该元素从当前位置存在,则在列表中返回下标。

例子: input_list =[3 42 42岁,31日,31日,31日,31日,5日,6日6日6日6日6日,7日,42)

从索引为0的列表第一个元素42开始,它检查元素42是否存在于input_list[1:]中(即从索引1到列表末尾)。 因为42存在于input_list[1:]中,它将返回42。

然后它转到下一个索引为1的元素31,并检查元素31是否存在于input_list[2:](即从索引2到列表末尾), 因为31存在于input_list[2:]中,它将返回31。

类似地,它遍历列表中的所有元素,只将重复/重复的元素返回到列表中。

然后,因为列表中有重复项,我们需要从每个重复项中选择一个,即从重复项中删除重复项,为此,我们调用python内置的名为set()的函数,它会删除重复项,

然后我们就得到了一个集合,而不是一个列表,因此为了将集合转换为列表,我们使用类型转换,list(),它将元素集转换为列表。

方法2:

def dupes(ilist):
    temp_list = [] # initially, empty temporary list
    dupe_list = [] # initially, empty duplicate list
    for each in ilist:
        if each in temp_list: # Found a Duplicate element
            if not each in dupe_list: # Avoid duplicate elements in dupe_list
                dupe_list.append(each) # Add duplicate element to dupe_list
        else: 
            temp_list.append(each) # Add a new (non-duplicate) to temp_list

    return dupe_list

解释: 首先,我们创建两个空列表。 然后继续遍历列表中的所有元素,以查看temp_list(最初为空)中是否存在该元素。如果它不在temp_list中,则使用append方法将它添加到temp_list中。

如果它已经存在于temp_list中,这意味着列表中的当前元素是重复的,因此我们需要使用append方法将它添加到dupe_list中。

其他回答

在Python中,只需一次迭代就可以找到被愚弄的人,这是一个非常简单快速的方法:

testList = ['red', 'blue', 'red', 'green', 'blue', 'blue']

testListDict = {}

for item in testList:
  try:
    testListDict[item] += 1
  except:
    testListDict[item] = 1

print testListDict

输出内容如下:

>>> print testListDict
{'blue': 3, 'green': 1, 'red': 2}

这和更多在我的博客http://www.howtoprogramwithpython.com

简单地检查,对于所有列表项,如果一个项的第一个索引等于该项的最后一个索引:

>>> lastindex = lambda arr, el: len(arr) - arr[::-1].index(el) -1
>>> is_duplicate  = lambda arr, el: arr.index(el) != lastindex(arr, el)
>>> duplicates = lambda arr: [*set(x for x in arr if is_duplicate(arr, x))]
>>> 
>>> a=[2,3,5,7,11,13, 2,17,7,7,17,18,3,19,5,2,7,48,48,2,19]
>>> duplicates(a)
[2, 3, 5, 7, 48, 17, 19]
>>> 

在没有任何python数据结构的帮助下,你可以简单地尝试下面的代码。这将工作于寻找重复的各种输入,如字符串,列表等。

# finding duplicates in unsorted an array 
def duplicates(numbers):
    store=[]
    checked=[]
    for i in range(len(numbers)):
        counter =1 
        for j in range(i+1,len(numbers)):
            if numbers[i] not in checked and numbers[j]==numbers[i] :
                counter +=1 
        if counter > 1 :
            store.append(numbers[i])
            checked.append(numbers[i])
    return store

print(duplicates([1,2,2,3,3,3,4,4,5]))  # output:  [2, 3, 4]
print(duplicates("madam"))              # output:  ['m', 'a']

还有其他测试。当然要做……

set([x for x in l if l.count(x) > 1])

...代价太大了。使用下一个final方法大约快500倍(数组越长结果越好):

def dups_count_dict(l):
    d = {}

    for item in l:
        if item not in d:
            d[item] = 0

        d[item] += 1

    result_d = {key: val for key, val in d.iteritems() if val > 1}

    return result_d.keys()

只有2个循环,没有非常昂贵的l.count()操作。

下面是一个比较方法的代码。代码如下,输出如下:

dups_count: 13.368s # this is a function which uses l.count()
dups_count_dict: 0.014s # this is a final best function (of the 3 functions)
dups_count_counter: 0.024s # collections.Counter

测试代码:

import numpy as np
from time import time
from collections import Counter

class TimerCounter(object):
    def __init__(self):
        self._time_sum = 0

    def start(self):
        self.time = time()

    def stop(self):
        self._time_sum += time() - self.time

    def get_time_sum(self):
        return self._time_sum


def dups_count(l):
    return set([x for x in l if l.count(x) > 1])


def dups_count_dict(l):
    d = {}

    for item in l:
        if item not in d:
            d[item] = 0

        d[item] += 1

    result_d = {key: val for key, val in d.iteritems() if val > 1}

    return result_d.keys()


def dups_counter(l):
    counter = Counter(l)    

    result_d = {key: val for key, val in counter.iteritems() if val > 1}

    return result_d.keys()



def gen_array():
    np.random.seed(17)
    return list(np.random.randint(0, 5000, 10000))


def assert_equal_results(*results):
    primary_result = results[0]
    other_results = results[1:]

    for other_result in other_results:
        assert set(primary_result) == set(other_result) and len(primary_result) == len(other_result)


if __name__ == '__main__':
    dups_count_time = TimerCounter()
    dups_count_dict_time = TimerCounter()
    dups_count_counter = TimerCounter()

    l = gen_array()

    for i in range(3):
        dups_count_time.start()
        result1 = dups_count(l)
        dups_count_time.stop()

        dups_count_dict_time.start()
        result2 = dups_count_dict(l)
        dups_count_dict_time.stop()

        dups_count_counter.start()
        result3 = dups_counter(l)
        dups_count_counter.stop()

        assert_equal_results(result1, result2, result3)

    print 'dups_count: %.3f' % dups_count_time.get_time_sum()
    print 'dups_count_dict: %.3f' % dups_count_dict_time.get_time_sum()
    print 'dups_count_counter: %.3f' % dups_count_counter.get_time_sum()

我没有看到一个纯粹使用迭代器的解决方案,所以我们开始吧

这需要对列表进行排序,这可能是这里的缺点。

a = [1,2,3,2,1,5,6,5,5,5]
a.sort()
set(map(lambda x: x[0], filter(lambda x: x[0] == x[1], zip(a, a[1:]))))

{1, 2, 5}

你可以用这段代码轻松检查你的机器有多快,有一百万潜在的重复:

首先生成数据

import random
from itertools import chain
a = list(chain(*[[n] * random.randint(1, 2) for n in range(1000000)]))

并运行测试:

set(map(lambda x: x[0], filter(lambda x: x[0] == x[1], zip(a, a[1:]))))

不用说,这个解决方案只在列表已经排序的情况下才有效。