13 Stimmen

Duplikate zwischen 2 Listen zählen

a = [1, 2, 9, 5, 1]
b = [9, 8, 7, 6, 5]

Ich möchte die Anzahl der Duplikate zwischen den beiden Listen zählen. Mit der obigen Formel möchte ich also den Wert 2 zurückgeben, da 9 und 5 in beiden Listen vorkommen.

Ich habe etwas Ähnliches versucht, aber es hat nicht ganz funktioniert.

def filter_(x, y):
    count = 0
    for num in y:
        if num in x:
            count += 1
            return count

0 Stimmen

Beachten Sie, dass, sobald es funktioniert (Entnahme der return zweimal), hat es O(n * m) komplex, d.h. skaliert ziemlich furchtbar.

0 Stimmen

@delnan danke für den Tipp. so mit Schnittpunkt Skalen besser.

0 Stimmen

Ja. Sie können sogar noch besser, aber das erfordert mehr als eine Zeile Code (die Idee ist, dass Sie nur eine Menge der ersten Liste benötigen, dann iterieren über die zweite und behalten die Elemente, die in der Menge sind - spart die Erstellung einer zweiten Menge).

34voto

user225312 Punkte 117771

Kürzere Wege und besser:

>>> a = [1, 2, 9, 5, 1]
>>> b = [9, 8, 7, 6, 5]
>>> len(set(a) & set(b))     # & is intersection - elements common to both
2 

Warum Ihr Code nicht funktioniert:

>>> def filter_(x, y):
...     count = 0
...     for num in y:
...             if num in x:
...                     count += 1
...     return count
... 
>>> filter_(a, b)
2

Ihr return count befand sich innerhalb der for-Schleife und kehrte zurück, ohne dass die Ausführung abgeschlossen war.

10voto

miku Punkte 170688

Sie können verwenden set.intersection :

>>> set(a).intersection(set(b)) # or just: set(a).intersection(b)
set([9, 5])

Oder, für die Länge der Kreuzung:

>>> len(set(a).intersection(set(b)))
2

Oder, knapper formuliert:

>>> len(set(a) & set(b))
2

0 Stimmen

Ich will keine 9,5. Ich will eine Zahl von 2.

0 Stimmen

Es ist nicht notwendig, explizit eine Menge aus der Liste b zu bilden, die Methode der Mengenüberschneidung unterstützt Listen als Eingaben.

8voto

Hugh Bothwell Punkte 52831

Wenn Sie mehrstellige Einträge zählen wollen, versagen die mengenbasierten Lösungen; Sie benötigen dann etwas wie

from collections import Counter

def numDups(a, b):
    if len(a)>len(b):
        a,b = b,a

    a_count = Counter(a)
    b_count = Counter(b)

    return sum(min(b_count[ak], av) for ak,av in a_count.iteritems())

dann

numDups([1,1,2,3], [1,1,1,1,1])

kehrt 2. Die Laufzeit hierfür beträgt O(n+m).

Außerdem ist Ihre ursprüngliche Lösung

for num in y:
    if num in x:
        count += 1

ist falsch - angewandt auf [1,2,3,3] und [1,1,1,1,1,3] wird Ihr Code entweder 3 oder 6 zurückgeben, weder davon ist richtig (Antwort sollte 2 sein).

0 Stimmen

Diese Lösung ist besser, weil sie auch die Duplikate zählt, danke :)

3voto

eduffy Punkte 37562

Konvertieren Sie sie in set s und zählen Sie die Schnittpunkte.

 len(set(a).intersection(set(b)))

1voto

Markus Punkte 654

Bei der folgenden Lösung werden auch doppelte Elemente in der Liste berücksichtigt:

from collections import Counter

def number_of_duplicates(list_a, list_b):
    count_a = Counter(list_a)
    count_b = Counter(list_b)

    common_keys = set(count_a.keys()).intersection(count_b.keys())
    return sum(min(count_a[key], count_b[key]) for key in common_keys)

Dann number_of_duplicates([1, 2, 2, 2, 3], [1, 2, 2, 4]) führt zu den erwarteten 3 .


Beachten Sie, dass @Hugh Bothwell auch eine ähnliche Lösung bereitgestellt hat, die jedoch manchmal zu Fehlern führt KeyError wenn ein Element nur in der kürzeren Liste enthalten ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X