Как найти повторяющиеся элементы в массиве, используя для цикла в 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
. Я не хочу удалять элементы из списка.
Но я хочу использовать здесь цикл.
Обычно 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
.
Ответы
Ответ 1
Только для информации. В 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]
Ответ 2
Используйте оператор 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"
Ответ 3
Вы всегда можете использовать понимание списка:
dups = [x for x in list_a if list_a.count(x) > 1]
Ответ 4
Перед 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(), и он даже встроен после:
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
, обеспечивающий ту же самую функцию, что и диктофон, и мы можем сделать его короче (и быстрее, возможно, 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.
Ответ 5
Вы можете использовать эту функцию для поиска дубликатов:
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]
Ответ 6
Если вы ищете сопоставление "один к одному" между вашими вложенными циклами и 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
(как указано выше).
Ответ 7
Следующее требует, чтобы элементы вашего списка были хешируемыми (а не только реализация __eq__
).
Я считаю, что более pythonic использовать 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]
Ответ 8
Использование только 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}
Ответ 9
Похоже, что у вас есть список (list_a
), который может содержать дубликаты, которые вы бы сохранили, и создайте дублированный список tmp
на основе list_a. В Python 2.7 вы можете выполнить это с помощью одной строки:
tmp = list(set(list_a))
Сравнение длин tmp
и list_a
в этот момент должно уточнить, действительно ли были дублированные элементы в list_a
. Это может помочь упростить ситуацию, если вы хотите перейти в цикл для дополнительной обработки.
Ответ 10
Вы можете просто "перевести" его по строкам.
С++
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 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):
Ответ 11
Использование 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]])
Ответ 12
Просто быстро и грязно,
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]
Ответ 13
В случае 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)
Ответ 14
Конечно, я не делал тестов, но, по-моему, будет сложно превзойти pandas в скорости:
pd.DataFrame(list_a, columns=["x"]).groupby('x').size().to_dict()
Ответ 15
Ты можешь использовать:
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}
Ответ 16
Немного больше реализации Pythonic (не самое, конечно), но в духе вашего кода C может быть:
for i, elem in enumerate(seq):
if elem in seq[i+1:]:
print elem
Изменить: да, он печатает элементы более одного раза, если есть более 2 повторений, но это то, что делает псевдо-код op C.