Как найти повторяющиеся элементы в массиве с помощью цикла for в Python?

У меня есть список с повторяющимися элементами:

 list_a=[1,2,3,5,6,7,5,2]

 tmp=[]

 for i in list_a:
     if tmp.__contains__(i):
         print i
     else:
         tmp.append(i)

Я использовал приведенный выше код, чтобы найти повторяющиеся элементы в файле list_a. Я не хочу удалять элементы из списка.

Но я хочу использовать цикл for здесь. Обычно C/C++ мы используем так, я думаю:

 for (int i=0;i<=list_a.length;i++)
     for (int j=i+1;j<=list_a.length;j++)
         if (list_a[i]==list_a[j])
             print list_a[i]

как мы используем это в Python?

for i in list_a:
    for j in list_a[1:]:
    ....

Я попробовал приведенный выше код. Но это неправильное решение. Я не знаю, как увеличить значение для j.


person Beginner    schedule 17.12.2009    source источник


Ответы (17)


Просто для информации. В python 2.7+ мы можем использовать Counter

import collections

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

>>> x
[1, 2, 3, 5, 6, 7, 5, 2]

>>> y=collections.Counter(x)
>>> y
Counter({2: 2, 5: 2, 1: 1, 3: 1, 6: 1, 7: 1})

Уникальный список

>>> list(y)
[1, 2, 3, 5, 6, 7]

Предметы найдены более 1 раза

>>> [i for i in y if y[i]>1]
[2, 5]

Предметы найдены только один раз

>>> [i for i in y if y[i]==1]
[1, 3, 6, 7]
person YOU    schedule 17.12.2009
comment
[n for n, i in y.iteritems() if i > 1] вместо этого и i == 1. - person ; 17.12.2009
comment
... но почему список (y) не является итерируемым счетчиком? - person LeMiz; 17.12.2009
comment
@ Роджер Пейт, спасибо, вам не нужно искать в диктофоне, это могло бы быть лучше. - person YOU; 17.12.2009
comment
Единственным недостатком счетчика является то, что он не завершается раньше, если дубликаты обнаруживаются в начале большого списка, и не работает для бесконечного итератора. - person Lie Ryan; 25.09.2012
comment
Мое решение: для k, v в x.most_common(): если v › 1: напечатать k - person luistm; 03.07.2014

Используйте оператор in вместо прямого вызова __contains__.

То, что у вас есть, почти работает (но это O (n ** 2)):

for i in xrange(len(list_a)):
  for j in xrange(i + 1, len(list_a)):
    if list_a[i] == list_a[j]:
      print "duplicate:", list_a[i]

Но гораздо проще использовать набор (примерно O(n) из-за хеш-таблицы):

seen = set()
for n in list_a:
  if n in seen:
    print "duplicate:", n
  else:
    seen.add(n)

Или dict, если вы хотите отслеживать расположение дубликатов (также O (n)):

import collections
items = collections.defaultdict(list)
for i, item in enumerate(list_a):
  items[item].append(i)
for item, locs in items.iteritems():
  if len(locs) > 1:
    print "duplicates of", item, "at", locs

Или даже просто обнаружить где-то дубликат (тоже O(n)):

if len(set(list_a)) != len(list_a):
  print "duplicate"
person Community    schedule 17.12.2009

Вы всегда можете использовать понимание списка:

dups = [x for x in list_a if list_a.count(x) > 1]
person Evan Fosmark    schedule 17.12.2009
comment
Это пересекает список один раз для каждого элемента (хотя код OP тоже O (N ** 2). - person Alok Singhal; 17.12.2009
comment
Да, я понял, что это неэффективно. Если ОП ищет это, он обязательно должен согласиться с ответами Роджера. - person Evan Fosmark; 17.12.2009
comment
Я думаю, что это немного более эффективно: [x for i,x in enumerate(list_a) if list_a[i:].count(x) › 1] - person Dmitry B.; 12.08.2011
comment
это вернет список с дубликатами, а list_a.count(x) › 1 вернет True для каждого вхождения элемента. Я бы использовал set() для получения уникальных дубликатов - person dmitko; 08.11.2012

До Python 2.3 используйте dict() :

>>> lst = [1, 2, 3, 5, 6, 7, 5, 2]
>>> stats = {}
>>> for x in lst : # count occurrences of each letter:
...     stats[x] = stats.get(x, 0) + 1 
>>> print stats
{1: 1, 2: 2, 3: 1, 5: 2, 6: 1, 7: 1} # filter letters appearing more than once:
>>> duplicates = [dup for (dup, i) in stats.items() if i > 1] 
>>> print duplicates

Итак, функция:

def getDuplicates(iterable):
    """
       Take an iterable and return a generator yielding its duplicate items.
       Items must be hashable.

       e.g :

       >>> sorted(list(getDuplicates([1, 2, 3, 5, 6, 7, 5, 2])))
       [2, 5]
    """
    stats = {}
    for x in iterable : 
        stats[x] = stats.get(x, 0) + 1
    return (dup for (dup, i) in stats.items() if i > 1)

В Python 2.3 появился set(), и он даже встроен после than :

def getDuplicates(iterable):
    """
       Take an iterable and return a generator yielding its duplicate items.
       Items must be hashable.

       e.g :

       >>> sorted(list(getDuplicates([1, 2, 3, 5, 6, 7, 5, 2])))
       [2, 5]
    """
    try: # try using built-in set
        found = set() 
    except NameError: # fallback on the sets module
        from sets import Set
        found = Set()

    for x in iterable:
        if x in found : # set is a collection that can't contain duplicate
            yield x
        found.add(x) # duplicate won't be added anyway

В Python 2.7 и более поздних версиях у вас есть модуль collections, предоставляющий ту же функцию, что и модуль dict, и мы можем сделать его короче (и быстрее, скорее всего, это C под капотом), чем решение 1:

import collections

def getDuplicates(iterable):
    """
       Take an iterable and return a generator yielding its duplicate items.
       Items must be hashable.

       e.g :

       >>> sorted(list(getDuplicates([1, 2, 3, 5, 6, 7, 5, 2])))
       [2, 5]
    """
    return (dup for (dup, i) in collections.counter(iterable).items() if i > 1)

Я бы остановился на решении 2.

person e-satis    schedule 17.12.2009

Вы можете использовать эту функцию для поиска дубликатов:

def get_duplicates(arr):
    dup_arr = arr[:]
    for i in set(arr):
        dup_arr.remove(i)       
    return list(set(dup_arr))

Примеры

print get_duplicates([1,2,3,5,6,7,5,2])

[2, 5]

print get_duplicates([1,2,1,3,4,5,4,4,6,7,8,2])

[1, 2, 4]

person ASKN    schedule 26.06.2012

Если вы ищете однозначное сопоставление между вашими вложенными циклами и Python, это то, что вам нужно:

n = len(list_a)
for i in range(n):
    for j in range(i+1, n):
        if list_a[i] == list_a[j]:
            print list_a[i]

Приведенный выше код не является "Pythonic". Я бы сделал это примерно так:

seen = set()
for i in list_a:
   if i in seen:
       print i
   else:
       seen.add(i)

Кроме того, не используйте __contains__, а используйте in (как указано выше).

person Alok Singhal    schedule 17.12.2009

Следующее требует, чтобы элементы вашего списка были хешируемыми (а не только реализация __eq__ ). Я считаю более питоническим использовать defaultdict (и у вас есть количество повторений бесплатно):

import collections
l = [1, 2, 4, 1, 3, 3]
d = collections.defaultdict(int)
for x in l:
   d[x] += 1
print [k for k, v in d.iteritems() if v > 1]
# prints [1, 3]
person LeMiz    schedule 17.12.2009
comment
Измените на if d[v] > 1, и я поставлю +1. - person Chris Lutz; 17.12.2009
comment
Крис: Я думаю, вы неправильно поняли этот ответ, он работает так, как сейчас, и ваше предложение сломает его. - person ; 17.12.2009

Используя только itertools, отлично работает на Python 2.5.

from itertools import groupby
list_a = sorted([1, 2, 3, 5, 6, 7, 5, 2])
result = dict([(r, len(list(grp))) for r, grp in groupby(list_a)])

Результат:

{1: 1, 2: 2, 3: 1, 5: 2, 6: 1, 7: 1}
person Zoran Pavlovic    schedule 28.01.2016

Похоже, у вас есть список (list_a), потенциально содержащий дубликаты, которые вы бы предпочли оставить как есть, и создать дедублированный список tmp на основе list_a. В Python 2.7 это можно сделать одной строкой:

tmp = list(set(list_a))

Сравнение длин tmp и list_a на этом этапе должно выяснить, действительно ли в list_a были повторяющиеся элементы. Это может помочь упростить вещи, если вы хотите войти в цикл для дополнительной обработки.

person Ahmer Kureishi    schedule 27.01.2013

Вы можете просто «перевести» его построчно.

c++

for (int i=0;i<=list_a.length;i++)
    for (int j=i+1;j<=list_a.length;j++)
        if (list_a[i]==list_a[j])
            print list_a[i]

Питон

for i in range(0, len(list_a)):
    for j in range(i + 1, len(list_a))
        if list_a[i] == list_a[j]:
            print list_a[i]

С++ для цикла:

for(int x = start; x < end; ++x)

Эквивалент Python:

for x in range(start, end):
person Fire Lancer    schedule 17.12.2009
comment
Вы не должны принимать этот ответ. Да, это правильный код, но это не тот способ, которым вы должны кодировать в Python. Не кодируйте Python как C/C++ или Java. Это разные языки, и они не предназначены для одинакового использования. - person e-satis; 17.12.2009
comment
Я согласен с e-satis, хотя вопрос специально пытается сравнить процедуру с C/C++, мы должны попытаться подтолкнуть ее в правильном направлении. - person Mizipzor; 17.12.2009

Просто быстро и грязно,

list_a=[1,2,3,5,6,7,5,2] 
holding_list=[]

for x in list_a:
    if x in holding_list:
        pass
    else:
        holding_list.append(x)

print holding_list

Выход [1, 2, 3, 5, 6, 7]

person Komu    schedule 26.09.2013

Использование numpy:

import numpy as np
count,value = np.histogram(list_a,bins=np.hstack((np.unique(list_a),np.inf)))
print 'duplicate value(s) in list_a: ' + ', '.join([str(v) for v in value[count>1]])
person Juh_    schedule 04.04.2012

В случае Python3 и если у вас два списка

def removedup(List1,List2):
    List1_copy = List1[:]
        for i in List1_copy:
            if i in List2:
                List1.remove(i)

List1 = [4,5,6,7]
List2 = [6,7,8,9]
removedup(List1,List2)
print (List1)
person Prashant Lakhera    schedule 26.01.2017

Конечно, я не проводил тестов, но думаю, что будет сложно превзойти панд по скорости:

 pd.DataFrame(list_a, columns=["x"]).groupby('x').size().to_dict()
person Make42    schedule 10.07.2017

Ты можешь использовать:

b=['E', 'P', 'P', 'E', 'O', 'E']
c={}
for i in b:
    value=0
    for j in b:
        if(i == j):
            value+=1
            c[i]=value
print(c)

Выход:

{'E': 3, 'P': 2, 'O': 1}
person Prince Vijay    schedule 09.06.2019

Поиск дубликатов в списке с помощью циклов, условной логики, логических операторов и методов списка.

some_list = ['a','b','c','d','e','b','n','n','c','c','h',]

duplicates = [] 

for values in some_list:

    if some_list.count(values) > 1:

        if values not in duplicates:

            duplicates.append(values)

print("Duplicate Values are : ",duplicates)  
   
person Zaheer Niazi    schedule 21.11.2020
comment
Как получить это без использования какой-либо библиотеки Python, такой как count? @Zaheer - person Navi; 27.11.2020

Чуть более питоническая реализация (не самая, конечно), но в духе вашего кода на Си могла бы быть:

for i, elem in enumerate(seq):
    if elem in seq[i+1:]:
        print elem

Редактировать: да, он печатает элементы более одного раза, если повторений более 2, но это то, что делает и псевдокод оператора C.

person fortran    schedule 17.12.2009
comment
Вы должны отсортировать, прежде чем делать это. Используйте отсортированные. Более того, вы будете печатать один и тот же дубликат несколько раз, если их несколько. - person e-satis; 17.12.2009
comment
Это будет печатать один и тот же элемент несколько раз, если он встречается в списке более 2 раз. - person truppo; 17.12.2009
comment
Вы, ребята, удосужились прочитать код операции? Делает точно так же. @ e-satis Нет необходимости сортировать, может быть, вы имели в виду что-то вроде [k for k, it in itertools.groupby(sorted(l)) if len(list(it)) > 1] ? - person fortran; 17.12.2009