Wie kann ich die Duplikate in einer Python-Liste finden und eine weitere Liste der Duplikate erstellen? Die Liste enthält nur Ganzzahlen.
Um Duplikate zu entfernen, verwenden Sie set(a)
. So drucken Sie Duplikate:
a = [1,2,3,2,1,5,6,5,5,5]
import collections
print [item for item, count in collections.Counter(a).items() if count > 1]
## [1, 2, 5]
Beachten Sie, dass Counter
nicht besonders effizient ist ( Timings ) und hier wahrscheinlich zu viel zu viel ist. set
wird bessere Ergebnisse erzielen. Dieser Code berechnet eine Liste eindeutiger Elemente in der Quellreihenfolge:
seen = set()
uniq = []
for x in a:
if x not in seen:
uniq.append(x)
seen.add(x)
oder genauer:
seen = set()
uniq = [x for x in a if x not in seen and not seen.add(x)]
Ich empfehle den letzteren Stil nicht, weil es nicht offensichtlich ist, was not seen.add(x)
tut (die set add()
-Methode gibt immer None
zurück, daher not
).
So berechnen Sie die Liste der duplizierten Elemente ohne Bibliotheken:
seen = {}
dupes = []
for x in a:
if x not in seen:
seen[x] = 1
else:
if seen[x] == 1:
dupes.append(x)
seen[x] += 1
Wenn Listenelemente nicht hashierbar sind, können Sie keine Mengen/Diagramme verwenden und müssen auf eine quadratische Zeitlösung zurückgreifen (vergleichen Sie jede mit jeder). Zum Beispiel:
a = [[1], [2], [3], [1], [5], [3]]
no_dupes = [x for n, x in enumerate(a) if x not in a[:n]]
print no_dupes # [[1], [2], [3], [5]]
dupes = [x for n, x in enumerate(a) if x in a[:n]]
print dupes # [[1], [3]]
>>> l = [1,2,3,4,4,5,5,6,1]
>>> set([x for x in l if l.count(x) > 1])
set([1, 4, 5])
Sie brauchen nicht die Zählung, nur ob der Gegenstand zuvor gesehen wurde oder nicht. diese Antwort an dieses Problem angepasst:
def list_duplicates(seq):
seen = set()
seen_add = seen.add
# adds all elements it doesn't know yet to seen and all other to seen_twice
seen_twice = set( x for x in seq if x in seen or seen_add(x) )
# turn the set into a list (as requested)
return list( seen_twice )
a = [1,2,3,2,1,5,6,5,5,5]
list_duplicates(a) # yields [1, 2, 5]
Für den Fall, dass es auf Geschwindigkeit ankommt, sind hier einige Timings:
# file: test.py
import collections
def thg435(l):
return [x for x, y in collections.Counter(l).items() if y > 1]
def moooeeeep(l):
seen = set()
seen_add = seen.add
# adds all elements it doesn't know yet to seen and all other to seen_twice
seen_twice = set( x for x in l if x in seen or seen_add(x) )
# turn the set into a list (as requested)
return list( seen_twice )
def RiteshKumar(l):
return list(set([x for x in l if l.count(x) > 1]))
def JohnLaRooy(L):
seen = set()
seen2 = set()
seen_add = seen.add
seen2_add = seen2.add
for item in L:
if item in seen:
seen2_add(item)
else:
seen_add(item)
return list(seen2)
l = [1,2,3,2,1,5,6,5,5,5]*100
Hier sind die Ergebnisse: (gut gemacht @JohnLaRooy!)
$ python -mtimeit -s 'import test' 'test.JohnLaRooy(test.l)'
10000 loops, best of 3: 74.6 usec per loop
$ python -mtimeit -s 'import test' 'test.moooeeeep(test.l)'
10000 loops, best of 3: 91.3 usec per loop
$ python -mtimeit -s 'import test' 'test.thg435(test.l)'
1000 loops, best of 3: 266 usec per loop
$ python -mtimeit -s 'import test' 'test.RiteshKumar(test.l)'
100 loops, best of 3: 8.35 msec per loop
Interessanterweise ändert sich neben den Timings auch das Ranking bei Verwendung von Pypy geringfügig. Interessanterweise profitiert der Counter-basierte Ansatz enorm von den Optimierungen von Pypy, während der von mir vorgeschlagene Methoden-Caching-Ansatz so gut wie keine Wirkung zu haben scheint.
$ pypy -mtimeit -s 'import test' 'test.JohnLaRooy(test.l)'
100000 loops, best of 3: 17.8 usec per loop
$ pypy -mtimeit -s 'import test' 'test.thg435(test.l)'
10000 loops, best of 3: 23 usec per loop
$ pypy -mtimeit -s 'import test' 'test.moooeeeep(test.l)'
10000 loops, best of 3: 39.3 usec per loop
Offensichtlich hängt dieser Effekt mit der "Verdoppelung" der Eingabedaten zusammen. Ich habe l = [random.randrange(1000000) for i in xrange(10000)]
eingestellt und habe folgende Ergebnisse erhalten:
$ pypy -mtimeit -s 'import test' 'test.moooeeeep(test.l)'
1000 loops, best of 3: 495 usec per loop
$ pypy -mtimeit -s 'import test' 'test.JohnLaRooy(test.l)'
1000 loops, best of 3: 499 usec per loop
$ pypy -mtimeit -s 'import test' 'test.thg435(test.l)'
1000 loops, best of 3: 1.68 msec per loop
Ich stieß auf diese Frage, als ich mich mit etwas verwandten beschäftigte - und wundere mich, warum niemand eine Generator-basierte Lösung anbot. Die Lösung dieses Problems wäre:
>>> print list(getDupes_9([1,2,3,2,1,5,6,5,5,5]))
[1, 2, 5]
Ich befasste mich mit der Skalierbarkeit, also testete ich verschiedene Ansätze, darunter naive Elemente, die gut für kleine Listen geeignet sind, aber mit zunehmender Größe schrecklich skalieren (Hinweis - hätte besser die Zeit verwendet, aber dies ist illustrativ).
Ich habe @moooeeeep zum Vergleich hinzugefügt (es ist beeindruckend schnell: am schnellsten, wenn die Eingabeliste völlig zufällig ist) und ein itertools-Ansatz, der für meist sortierte Listen noch schneller ist ... Jetzt enthält Pandas-Ansatz von @firelynx - langsam, aber nicht schrecklich so und einfach. Hinweis - Die Sortierung/Abschlag-/Zip-Methode ist auf meinem Computer für große, meistens geordnete Listen durchweg am schnellsten. Moooeeeep ist bei gemischten Listen am schnellsten. Die Laufleistung kann jedoch variieren.
Vorteile
Annahmen
Schnellste Lösung mit 1m Einträgen:
def getDupes(c):
'''sort/tee/izip'''
a, b = itertools.tee(sorted(c))
next(b, None)
r = None
for k, g in itertools.izip(a, b):
if k != g: continue
if k != r:
yield k
r = k
Ansätze getestet
import itertools
import time
import random
def getDupes_1(c):
'''naive'''
for i in xrange(0, len(c)):
if c[i] in c[:i]:
yield c[i]
def getDupes_2(c):
'''set len change'''
s = set()
for i in c:
l = len(s)
s.add(i)
if len(s) == l:
yield i
def getDupes_3(c):
'''in dict'''
d = {}
for i in c:
if i in d:
if d[i]:
yield i
d[i] = False
else:
d[i] = True
def getDupes_4(c):
'''in set'''
s,r = set(),set()
for i in c:
if i not in s:
s.add(i)
Elif i not in r:
r.add(i)
yield i
def getDupes_5(c):
'''sort/adjacent'''
c = sorted(c)
r = None
for i in xrange(1, len(c)):
if c[i] == c[i - 1]:
if c[i] != r:
yield c[i]
r = c[i]
def getDupes_6(c):
'''sort/groupby'''
def multiple(x):
try:
x.next()
x.next()
return True
except:
return False
for k, g in itertools.ifilter(lambda x: multiple(x[1]), itertools.groupby(sorted(c))):
yield k
def getDupes_7(c):
'''sort/Zip'''
c = sorted(c)
r = None
for k, g in Zip(c[:-1],c[1:]):
if k == g:
if k != r:
yield k
r = k
def getDupes_8(c):
'''sort/izip'''
c = sorted(c)
r = None
for k, g in itertools.izip(c[:-1],c[1:]):
if k == g:
if k != r:
yield k
r = k
def getDupes_9(c):
'''sort/tee/izip'''
a, b = itertools.tee(sorted(c))
next(b, None)
r = None
for k, g in itertools.izip(a, b):
if k != g: continue
if k != r:
yield k
r = k
def getDupes_a(l):
'''moooeeeep'''
seen = set()
seen_add = seen.add
# adds all elements it doesn't know yet to seen and all other to seen_twice
for x in l:
if x in seen or seen_add(x):
yield x
def getDupes_b(x):
'''iter*/sorted'''
x = sorted(x)
def _matches():
for k,g in itertools.izip(x[:-1],x[1:]):
if k == g:
yield k
for k, n in itertools.groupby(_matches()):
yield k
def getDupes_c(a):
'''pandas'''
import pandas as pd
vc = pd.Series(a).value_counts()
i = vc[vc > 1].index
for _ in i:
yield _
def hasDupes(fn,c):
try:
if fn(c).next(): return True # Found a dupe
except StopIteration:
pass
return False
def getDupes(fn,c):
return list(fn(c))
STABLE = True
if STABLE:
print 'Finding FIRST then ALL duplicates, single dupe of "nth" placed element in 1m element array'
else:
print 'Finding FIRST then ALL duplicates, single dupe of "n" included in randomised 1m element array'
for location in (50,250000,500000,750000,999999):
for test in (getDupes_2, getDupes_3, getDupes_4, getDupes_5, getDupes_6,
getDupes_8, getDupes_9, getDupes_a, getDupes_b, getDupes_c):
print 'Test %-15s:%10d - '%(test.__doc__ or test.__name__,location),
deltas = []
for FIRST in (True,False):
for i in xrange(0, 5):
c = range(0,1000000)
if STABLE:
c[0] = location
else:
c.append(location)
random.shuffle(c)
start = time.time()
if FIRST:
print '.' if location == test(c).next() else '!',
else:
print '.' if [location] == list(test(c)) else '!',
deltas.append(time.time()-start)
print ' -- %0.3f '%(sum(deltas)/len(deltas)),
print
print
Die Ergebnisse für den Test "Alle Dupes" waren konsistent und fanden "zuerst" Duplikate und dann "Alle" Duplikate in diesem Array:
Finding FIRST then ALL duplicates, single dupe of "nth" placed element in 1m element array
Test set len change : 500000 - . . . . . -- 0.264 . . . . . -- 0.402
Test in dict : 500000 - . . . . . -- 0.163 . . . . . -- 0.250
Test in set : 500000 - . . . . . -- 0.163 . . . . . -- 0.249
Test sort/adjacent : 500000 - . . . . . -- 0.159 . . . . . -- 0.229
Test sort/groupby : 500000 - . . . . . -- 0.860 . . . . . -- 1.286
Test sort/izip : 500000 - . . . . . -- 0.165 . . . . . -- 0.229
Test sort/tee/izip : 500000 - . . . . . -- 0.145 . . . . . -- 0.206 *
Test moooeeeep : 500000 - . . . . . -- 0.149 . . . . . -- 0.232
Test iter*/sorted : 500000 - . . . . . -- 0.160 . . . . . -- 0.221
Test pandas : 500000 - . . . . . -- 0.493 . . . . . -- 0.499
Wenn die Listen zuerst gemischt werden, wird der Preis für die Sortierung sichtbar - die Effizienz sinkt merklich und der @moooeeeep-Ansatz wird dominiert, wobei die set & dict-Ansätze ähnlich sind, jedoch weniger leistungsfähige Künstler:
Finding FIRST then ALL duplicates, single dupe of "n" included in randomised 1m element array
Test set len change : 500000 - . . . . . -- 0.321 . . . . . -- 0.473
Test in dict : 500000 - . . . . . -- 0.285 . . . . . -- 0.360
Test in set : 500000 - . . . . . -- 0.309 . . . . . -- 0.365
Test sort/adjacent : 500000 - . . . . . -- 0.756 . . . . . -- 0.823
Test sort/groupby : 500000 - . . . . . -- 1.459 . . . . . -- 1.896
Test sort/izip : 500000 - . . . . . -- 0.786 . . . . . -- 0.845
Test sort/tee/izip : 500000 - . . . . . -- 0.743 . . . . . -- 0.804
Test moooeeeep : 500000 - . . . . . -- 0.234 . . . . . -- 0.311 *
Test iter*/sorted : 500000 - . . . . . -- 0.776 . . . . . -- 0.840
Test pandas : 500000 - . . . . . -- 0.539 . . . . . -- 0.540
Sie können iteration_utilities.duplicates
verwenden:
>>> from iteration_utilities import duplicates
>>> list(duplicates([1,1,2,1,2,3,4,2]))
[1, 1, 2, 2]
oder wenn Sie nur eines von jedem Duplikat wünschen, kann dies mit iteration_utilities.unique_everseen
kombiniert werden:
>>> from iteration_utilities import unique_everseen
>>> list(unique_everseen(duplicates([1,1,2,1,2,3,4,2])))
[1, 2]
Es kann auch mit unerschütterlichen Elementen umgehen (jedoch auf Kosten der Leistung):
>>> list(duplicates([[1], [2], [1], [3], [1]]))
[[1], [1]]
>>> list(unique_everseen(duplicates([[1], [2], [1], [3], [1]])))
[[1]]
Das ist etwas, was nur einige der anderen Ansätze hier bewältigen können.
Ich habe einen schnellen Benchmark erstellt, der die meisten (aber nicht alle) der hier genannten Ansätze enthält.
Der erste Benchmark umfasste nur einen kleinen Bereich von Listenlängen, da einige Ansätze O(n**2)
-Verhalten haben.
In den Diagrammen stellt die y-Achse die Zeit dar, ein niedrigerer Wert bedeutet also besser. Es wird auch ein Protokoll protokolliert, damit die verschiedenen Werte besser visualisiert werden können:
Entfernen der O(n**2)
-Ansätze Ich habe eine weitere Benchmark mit einer halben Million Elementen in einer Liste durchgeführt:
Wie Sie sehen, ist der iteration_utilities.duplicates
-Ansatz schneller als alle anderen Ansätze, und selbst die Verkettung unique_everseen(duplicates(...))
war schneller oder gleich schnell als die anderen Ansätze.
Interessant ist auch, dass die Pandas-Ansätze für kleine Listen sehr langsam sind, aber leicht um längere Listen konkurrieren können.
Da diese Benchmarks jedoch zeigen, dass die meisten Ansätze ungefähr gleich gut funktionieren, spielt es keine Rolle, welcher Ansatz verwendet wird (mit Ausnahme der 3, die O(n**2)
-Laufzeit hatten).
from iteration_utilities import duplicates, unique_everseen
from collections import Counter
import pandas as pd
import itertools
def georg_counter(it):
return [item for item, count in Counter(it).items() if count > 1]
def georg_set(it):
seen = set()
uniq = []
for x in it:
if x not in seen:
uniq.append(x)
seen.add(x)
def georg_set2(it):
seen = set()
return [x for x in it if x not in seen and not seen.add(x)]
def georg_set3(it):
seen = {}
dupes = []
for x in it:
if x not in seen:
seen[x] = 1
else:
if seen[x] == 1:
dupes.append(x)
seen[x] += 1
def RiteshKumar_count(l):
return set([x for x in l if l.count(x) > 1])
def moooeeeep(seq):
seen = set()
seen_add = seen.add
# adds all elements it doesn't know yet to seen and all other to seen_twice
seen_twice = set( x for x in seq if x in seen or seen_add(x) )
# turn the set into a list (as requested)
return list( seen_twice )
def F1Rumors_implementation(c):
a, b = itertools.tee(sorted(c))
next(b, None)
r = None
for k, g in Zip(a, b):
if k != g: continue
if k != r:
yield k
r = k
def F1Rumors(c):
return list(F1Rumors_implementation(c))
def Edward(a):
d = {}
for elem in a:
if elem in d:
d[elem] += 1
else:
d[elem] = 1
return [x for x, y in d.items() if y > 1]
def wordsmith(a):
return pd.Series(a)[pd.Series(a).duplicated()].values
def NikhilPrabhu(li):
li = li.copy()
for x in set(li):
li.remove(x)
return list(set(li))
def firelynx(a):
vc = pd.Series(a).value_counts()
return vc[vc > 1].index.tolist()
def HenryDev(myList):
newList = set()
for i in myList:
if myList.count(i) >= 2:
newList.add(i)
return list(newList)
def yota(number_lst):
seen_set = set()
duplicate_set = set(x for x in number_lst if x in seen_set or seen_set.add(x))
return seen_set - duplicate_set
def IgorVishnevskiy(l):
s=set(l)
d=[]
for x in l:
if x in s:
s.remove(x)
else:
d.append(x)
return d
def it_duplicates(l):
return list(duplicates(l))
def it_unique_duplicates(l):
return list(unique_everseen(duplicates(l)))
from simple_benchmark import benchmark
import random
funcs = [
georg_counter, georg_set, georg_set2, georg_set3, RiteshKumar_count, moooeeeep,
F1Rumors, Edward, wordsmith, NikhilPrabhu, firelynx,
HenryDev, yota, IgorVishnevskiy, it_duplicates, it_unique_duplicates
]
args = {2**i: [random.randint(0, 2**(i-1)) for _ in range(2**i)] for i in range(2, 12)}
b = benchmark(funcs, args, 'list size')
b.plot()
funcs = [
georg_counter, georg_set, georg_set2, georg_set3, moooeeeep,
F1Rumors, Edward, wordsmith, firelynx,
yota, IgorVishnevskiy, it_duplicates, it_unique_duplicates
]
args = {2**i: [random.randint(0, 2**(i-1)) for _ in range(2**i)] for i in range(2, 20)}
b = benchmark(funcs, args, 'list size')
b.plot()
1 Dies ist aus einer Fremdbibliothek, die ich geschrieben habe: iteration_utilities
.
collections.Counter ist neu in Python 2.7:
Python 2.5.4 (r254:67916, May 31 2010, 15:03:39)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
a = [1,2,3,2,1,5,6,5,5,5]
import collections
print [x for x, y in collections.Counter(a).items() if y > 1]
Type "help", "copyright", "credits" or "license" for more information.
File "", line 1, in
AttributeError: 'module' object has no attribute 'Counter'
>>>
In einer früheren Version können Sie stattdessen ein herkömmliches Diktat verwenden:
a = [1,2,3,2,1,5,6,5,5,5]
d = {}
for elem in a:
if elem in d:
d[elem] += 1
else:
d[elem] = 1
print [x for x, y in d.items() if y > 1]
Pandas benutzen:
>>> import pandas as pd
>>> a = [1, 2, 1, 3, 3, 3, 0]
>>> pd.Series(a)[pd.Series(a).duplicated()].values
array([1, 3, 3])
Hier ist eine ordentliche und prägnante Lösung -
for x in set(li):
li.remove(x)
li = list(set(li))
Ohne in eine Liste umzuwandeln und wahrscheinlich wäre der einfachste Weg etwas wie folgtDies kann während eines Interviews nützlich sein, wenn sie keine Sets verwenden möchten
a=[1,2,3,3,3]
dup=[]
for each in a:
if each not in dup:
dup.append(each)
print(dup)
======= else, um zwei separate Listen mit eindeutigen Werten und doppelten Werten zu erhalten
a=[1,2,3,3,3]
uniques=[]
dups=[]
for each in a:
if each not in uniques:
uniques.append(each)
else:
dups.append(each)
print("Unique values are below:")
print(uniques)
print("Duplicate values are below:")
print(dups)
Sie können einfach jedes Element in der Liste durchlaufen, indem Sie die Anzahl der Vorkommen überprüfen und dann zu einem Satz hinzufügen, der die Duplikate druckt. Hoffe, das hilft jemandem da draußen.
myList = [2 ,4 , 6, 8, 4, 6, 12];
newList = set()
for i in myList:
if myList.count(i) >= 2:
newList.add(i)
print(list(newList))
## [4 , 6]
Ich würde das mit Pandas machen, weil ich häufig Pandas benutze
import pandas as pd
a = [1,2,3,3,3,4,5,6,6,7]
vc = pd.Series(a).value_counts()
vc[vc > 1].index.tolist()
Gibt
[3,6]
Wahrscheinlich nicht sehr effizient, aber es ist sicher weniger Code als viele andere Antworten, also dachte ich, ich würde dazu beitragen
das dritte Beispiel der akzeptierten Antwort gibt eine falsche Antwort und versucht nicht, Duplikate zu geben. Hier ist die richtige Version:
number_lst = [1, 1, 2, 3, 5, ...]
seen_set = set()
duplicate_set = set(x for x in number_lst if x in seen_set or seen_set.add(x))
unique_set = seen_set - duplicate_set
Ein bisschen spät, aber vielleicht hilfreich für einige .. Für eine größere Liste fand ich, dass dies für mich funktionierte.
l=[1,2,3,5,4,1,3,1]
s=set(l)
d=[]
for x in l:
if x in s:
s.remove(x)
else:
d.append(x)
d
[1,3,1]
Zeigt nur und alle Duplikate und behält die Reihenfolge bei.
Eine sehr einfache und schnelle Möglichkeit, Dupes mit einer Iteration in Python zu finden, ist:
testList = ['red', 'blue', 'red', 'green', 'blue', 'blue']
testListDict = {}
for item in testList:
try:
testListDict[item] += 1
except:
testListDict[item] = 1
print testListDict
Die Ausgabe wird wie folgt sein:
>>> print testListDict
{'blue': 3, 'green': 1, 'red': 2}
Dies und mehr in meinem Blog http://www.howtoprogramwithpython.com
Wir können itertools.groupby
verwenden, um alle Elemente zu finden, die Dups enthalten:
from itertools import groupby
myList = [2, 4, 6, 8, 4, 6, 12]
# when the list is sorted, groupby groups by consecutive elements which are similar
for x, y in groupby(sorted(myList)):
# list(y) returns all the occurences of item x
if len(list(y)) > 1:
print x
Die Ausgabe wird sein:
4
6
Hier gibt es viele Antworten, aber ich denke, dass dies ein relativ lesbarer und leicht verständlicher Ansatz ist:
def get_duplicates(sorted_list):
duplicates = []
last = sorted_list[0]
for x in sorted_list[1:]:
if x == last:
duplicates.append(x)
last = x
return set(duplicates)
Anmerkungen:
Hier ist ein schneller Generator, der jedes Element mithilfe eines Diktiers als Schlüssel mit einem booleschen Wert speichert, um zu prüfen, ob das doppelte Element bereits vorhanden ist.
Für Listen mit allen Elementen, die hashable-Typen sind:
def gen_dupes(array):
unique = {}
for value in array:
if value in unique and unique[value]:
unique[value] = False
yield value
else:
unique[value] = True
array = [1, 2, 2, 3, 4, 1, 5, 2, 6, 6]
print(list(gen_dupes(array)))
# => [2, 1, 6]
Für Listen, die Listen enthalten könnten:
def gen_dupes(array):
unique = {}
for value in array:
is_list = False
if type(value) is list:
value = Tuple(value)
is_list = True
if value in unique and unique[value]:
unique[value] = False
if is_list:
value = list(value)
yield value
else:
unique[value] = True
array = [1, 2, 2, [1, 2], 3, 4, [1, 2], 5, 2, 6, 6]
print(list(gen_dupes(array)))
# => [2, [1, 2], 6]
Einige andere Tests. Natürlich zu tun ...
set([x for x in l if l.count(x) > 1])
... ist zu teuer. Es ist etwa 500-mal schneller (das längere Array liefert bessere Ergebnisse), um die nächste abschließende Methode zu verwenden:
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()
Nur 2 Schleifen, keine sehr kostspieligen l.count()
-Operationen.
Hier ist ein Code, um zum Beispiel die Methoden zu vergleichen. Der Code ist unten, hier ist die Ausgabe:
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
Der Testcode:
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 __== '__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()
raw_list = [1,2,3,3,4,5,6,6,7,2,3,4,2,3,4,1,3,4,]
clean_list = list(set(raw_list))
duplicated_items = []
for item in raw_list:
try:
clean_list.remove(item)
except ValueError:
duplicated_items.append(item)
print(duplicated_items)
# [3, 6, 2, 3, 4, 2, 3, 4, 1, 3, 4]
Sie entfernen Duplikate im Grunde genommen, indem Sie in set (clean_list
) konvertieren und dann den raw_list
iterieren, während Sie jede item
in der Bereinigungsliste für das Auftreten in raw_list
entfernen. Wenn item
nicht gefunden wird, wird die Ausnahmebedingung ValueError
abgefangen und die item
wird zur duplicated_items
-Liste hinzugefügt.
Wenn der Index duplizierter Elemente benötigt wird, enumerate
die Liste und spiele mit dem Index herum. (for index, item in enumerate(raw_list):
) das ist schneller und optimiert für große Listen (wie Tausende + von Elementen)
Einzeilige Lösung:
set([i for i in list if sum([1 for a in list if a == i]) > 1])
list2 = [1, 2, 3, 4, 1, 2, 3]
lset = set()
[(lset.add(item), list2.append(item))
for item in list2 if item not in lset]
print list(lset)
def removeduplicates(a):
seen = set()
for i in a:
if i not in seen:
seen.add(i)
return seen
print(removeduplicates([1,1,2,2]))
Methode 1:
list(set([val for idx, val in enumerate(input_list) if val in input_list[idx+1:]]))
Erläuterung: [Wert für idx, Wert in Aufzählung (input_list), wenn val in input_list [idx + 1:]] ein Listenverständnis ist, das ein Element zurückgibt, wenn dasselbe Element aus dem aktuellen Element vorhanden ist Position, in der Liste, den Index.
Beispiel: Input_list = [42,31,42,31,3,31,31,5,6,6,6,6,6,7,72]
beginnend mit dem ersten Element in Liste 42 mit Index 0 wird geprüft, ob das Element 42 in input_list [1:] vorhanden ist (dh vom Index 1 bis zum Ende der Liste) Weil 42 in input_list [vorhanden ist. 1:] wird 42 zurückgegeben.
Dann geht es mit Index 1 zum nächsten Element 31 und prüft, ob Element 31 in der input_list [2:] vorhanden ist (dh vom Index 2 bis zum Ende der Liste) Weil 31 in input_list [2 vorhanden ist :] wird 31 zurückgegeben.
in ähnlicher Weise werden alle Elemente in der Liste durchlaufen und es werden nur die wiederholten/doppelten Elemente in eine Liste zurückgegeben.
Da wir über Duplikate verfügen, müssen wir in einer Liste eines von jedem Duplikat auswählen, d. H. Duplikate zwischen den Duplikaten entfernen. Dazu rufen wir einen eingebauten Python namens named () auf, der die Duplikate entfernt.
Dann bleibt uns eine Menge, aber keine Liste, und um eine Menge in eine Liste umzuwandeln, verwenden wir typecasting, list () und konvertieren die Menge der Elemente in eine Liste.
Methode 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
Erläuterung: Hier erstellen wir zwei leere Listen, um mit ..__ zu beginnen. Durchlaufen Sie dann alle Elemente der Liste, um zu sehen, ob sie in temp_list vorhanden sind (zunächst leer). Wenn es nicht in der temporären Liste enthalten ist, fügen wir es mit der Methode append zur temporären Liste hinzu.
Wenn es bereits in temp_list vorhanden ist, bedeutet dies, dass das aktuelle Element der Liste ein Duplikat ist. Daher müssen wir es mithilfe der append -Methode zu dupe_list hinzufügen.
Ich komme sehr spät in diese Diskussion ein. Obwohl ich dieses Problem gerne mit einem Liner behandeln möchte. Weil dies der Charme von Python ist, wenn wir nur die Duplikate in eine separate Liste (oder in eine andere Sammlung) bringen wollen, würde ich vorschlagen, wie folgt vorzugehen. Wir haben eine doppelte Liste, die wir als 'target' bezeichnen können '
target=[1,2,3,4,4,4,3,5,6,8,4,3]
Wenn wir die Duplikate erhalten wollen, können wir den einen Liner wie folgt verwenden:
duplicates=dict(set((x,target.count(x)) for x in filter(lambda rec : target.count(rec)>1,target)))
Dieser Code fügt die duplizierten Datensätze als Schlüssel hinzu und zählt als Wert für das Wörterbuch 'Duplikate'. Das 'Duplikat' Wörterbuch sieht wie folgt aus:
{3: 3, 4: 4} #it saying 3 is repeated 3 times and 4 is 4 times
Wenn Sie nur alle Datensätze mit Duplikaten alleine in einer Liste haben möchten, ist der Code wiederum viel kürzer:
duplicates=filter(lambda rec : target.count(rec)>1,target)
Ausgabe wird sein:
[3, 4, 4, 4, 3, 4, 3]
Dies funktioniert perfekt in Python 2.7.x + -Versionen
so musste ich es tun, weil ich mich dazu herausforderte, keine anderen Methoden zu verwenden:
def dupList(oldlist):
if type(oldlist)==type((2,2)):
oldlist=[x for x in oldlist]
newList=[]
newList=newList+oldlist
oldlist=oldlist
forbidden=[]
checkPoint=0
for i in range(len(oldlist)):
#print 'start i', i
if i in forbidden:
continue
else:
for j in range(len(oldlist)):
#print 'start j', j
if j in forbidden:
continue
else:
#print 'after Else'
if i!=j:
#print 'i,j', i,j
#print oldlist
#print newList
if oldlist[j]==oldlist[i]:
#print 'oldlist[i],oldlist[j]', oldlist[i],oldlist[j]
forbidden.append(j)
#print 'forbidden', forbidden
del newList[j-checkPoint]
#print newList
checkPoint=checkPoint+1
return newList
so funktioniert Ihre Probe als:
>>>a = [1,2,3,3,3,4,5,6,6,7]
>>>dupList(a)
[1, 2, 3, 4, 5, 6, 7]
verwenden der Methode list.count()
in der Liste, um die doppelten Elemente einer bestimmten Liste zu ermitteln
arr=[]
dup =[]
for i in range(int(input("Enter range of list: "))):
arr.append(int(input("Enter Element in a list: ")))
for i in arr:
if arr.count(i)>1 and i not in dup:
dup.append(i)
print(dup)
Bei Verwendung von toolz :
from toolz import frequencies, valfilter
a = [1,2,2,3,4,5,4]
>>> list(valfilter(lambda count: count > 1, frequencies(a)).keys())
[2,4]