it-swarm.com.de

Wie finde ich die Duplikate in einer Liste und erstelle eine weitere Liste damit?

Wie kann ich die Duplikate in einer Python-Liste finden und eine weitere Liste der Duplikate erstellen? Die Liste enthält nur Ganzzahlen.

311
MFB

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]]
381
georg
>>> 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])
263
Ritesh Kumar

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
71
moooeeeep

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

  • sehr schnell und einfach auf "beliebige" Duplikate mit demselben Code zu testen

Annahmen

  • Duplikate sollten nur einmal gemeldet werden
  • Doppelte Reihenfolge muss nicht beibehalten werden
  • Duplikate können sich irgendwo in der Liste befinden

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  
27
F1Rumors

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.

Benchmarks

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:

 enter image description here

Entfernen der O(n**2)-Ansätze Ich habe eine weitere Benchmark mit einer halben Million Elementen in einer Liste durchgeführt:

 enter image description here

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)))

Benchmark 1

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()

Benchmark 2

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()

Haftungsausschluss

1 Dies ist aus einer Fremdbibliothek, die ich geschrieben habe: iteration_utilities .

19
MSeifert

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]
11
Edward

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])
10
wordsmith

Hier ist eine ordentliche und prägnante Lösung -

for x in set(li):
    li.remove(x)

li = list(set(li))
7
Nikhil Prabhu

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)
6

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]
6
HenryDev

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

5
firelynx

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
5
yota

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.

4
user3109122

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

3

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
3
alfasin

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:

  • Wenn Sie die Anzahl der Duplikate beibehalten möchten, entfernen Sie den Castto unten, um die vollständige Liste zu erhalten
  • Wenn Sie Generatoren bevorzugen, ersetzen Sie duplicates.append (x) durch-ertrag x und die return-Anweisung am unteren Rand (Sie können später umsetzen)
1
tvt173

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]
1
John B

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()
1
sergzach
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)

1

Einzeilige Lösung:

set([i for i in list if sum([1 for a in list if a == i]) > 1])
1
ytpillai
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)
1
Haresh Shyara
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]))
1
ASHISH RANJAN

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.

0
Sundeep Borra

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

0

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]
0
Matt S

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)
0
Ravikiran D

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] 
0
Andreas Profous