Python: Sehen Sie, ob ein Satz einen anderen vollständig enthält?


81

Gibt es eine schnelle Möglichkeit zu überprüfen, ob ein Satz einen anderen vollständig enthält?

Etwas wie:

>>>[1, 2, 3].containsAll([2, 1])
True

>>>[1, 2, 3].containsAll([3, 5, 9])
False

Antworten:


124

Das sind Listen, aber wenn Sie wirklich Mengen meinen, können Sie die issubset-Methode verwenden.

>>> s = set([1,2,3])
>>> t = set([1,2])
>>> t.issubset(s)
True
>>> s.issuperset(t)
True

Für eine Liste können Sie nichts Besseres tun, als jedes Element zu überprüfen.


3
Ich bekomme ein seltsames Gefühl von Dejavu, wenn ich diese Antwort sehe
Christophe Roussy

Sie müssen sich der Semantik von issubset()is notcontains()
wikier

37

Der Vollständigkeit issubsethalber : Dies entspricht (obwohl wohl etwas weniger explizit / lesbar):

>>> set([1,2,3]) >= set([2,1])
True
>>> set([1,2,3]) >= set([3,5,9])
False

Das Problem ist a = set ([]) und b = set (['a', 'b']), dann ist a.issubset (b) True
darkman

4

Eine Option bleibt unberührt - Subtraktion:

>>> {1, 2} - {1, 2, 3}
set([])
>>> {1, 2, 3} - {1, 2}
set([3])

Grundsätzlich prüfen Sie, welche Elemente in der ersten Liste nicht in der zweiten Liste enthalten sind.

Ich fand es sehr praktisch, da Sie zeigen konnten, welche Werte fehlen:

>>> def check_contains(a, b):
...     diff = a - b
...     if not diff:
...         # All elements from a are present in b
...         return True
...     print('Some elements are missing: {}'.format(diff))
...     return False
...
>>> check_contains({1, 2}, {1, 2, 3})
True
>>> check_contains({1, 2, 3}, {1, 2})
Some elements are missing: set([3])
False

3

Sie können entweder set.issubset()oder set.issuperset()(oder deren auf Operatoren basierende Gegenstücke verwenden: <=und >=). Beachten Sie, dass die Methoden alle iterierbaren Elemente als Argument akzeptieren , nicht nur eine Menge:

>>> {1, 2}.issubset([1, 2, 3])
True
>>> {1, 2, 3}.issuperset([1, 2])
True

Wenn Sie jedoch Operatoren verwenden, müssen beide Argumente gesetzt sein:

>>> {1, 2} <= {1, 2, 3}
True
>>> {1, 2, 3} >= {1, 2}
True

3

Wenn Sie vermuten, dass eine Menge eine Teilmenge einer anderen ist und diese beiden Mengen miteinander überschneiden, ist das Ergebnis gleich, wenn es sich um eine Teilmenge handelt.

a = [2,1,3,3]
b = [5,4,3,2,1]
set(a).intersection(set(b)) == set(a)
>>True

1
Lass A = set(a)und B = set(b)für die Vernunft. Dann ist dieser Vergleich effizient auf reduzierbar len(A.intersection(B)) == len(A). Das heißt, die Mengen selbst müssen nicht elementweise verglichen werden; Es muss nur die Kardinalität dieser Mengen verglichen werden. Selbst diese Optimierung reicht wahrscheinlich nicht aus, um diesen Ansatz vorzuziehen. Die dramatisch besser lesbar und effizient issubset()und <=Ansätze sind fast sicher , was alle wollen.
Cecil Curry

@CecilCurry True - Ich habe das Wort "Kardinalität" falsch verwendet, da es sich um eine Längenmessung handelt. Ich habe den Wortlaut aktualisiert. Ihre Optimierung ist ein Fehler, der auf meinem Fehler basiert. Keine Optimierung. Der wörtliche Wortlaut von "intersection ()" lautet expliziter als die überladenen Implikationen von "> =" und die Aussage, dass "issubset ()" leichter zu lesen ist, ist eine Art Eliminierung des Offensichtlichen, da es die beliebteste Antwort ist. Fühlen Sie sich frei, eine kreative Lösung beizutragen, die über die Wiederholung der Antworten anderer hinausgeht.
Jordan Stefanelli

0

Unterhalb der Funktion wird 0 zurückgegeben, wenn die Hauptliste die Unterliste nicht vollständig enthält, und 1, wenn sie vollständig enthält.

def islistsubset(sublist,mainlist):
     for item in sublist:
             if item in mainlist:
                     contains = 1
             else:
                     contains = 0
                     break;
     return contains

1
Dies ist O (n ^ 2), während die Verwendung von Set-Operationen, wie in einigen der vorhandenen Antworten, viel schneller ist. Dies kann auch einfach geschrieben werden any(item in mainlist for item in sublist).
Iguananaut

Ich stimme zu, dass ich auch def islistsubset (Unterliste, Hauptliste) schreiben könnte: enthält = 1 für Element in Unterliste: wenn Element in Hauptliste: weiter sonst: enthält = 0 break; Rückkehr enthält also nur 2 Aufgaben pro Anruf
Bobin Motti Thomas

@BobinMottiThomas Sie können einfach direkt True oder False zurückgeben, ohne eine temporäre Variable zu erstellen. für Artikel in list_a: wenn Artikel nicht in list_b: return False return True
Jordan Stefanelli

0
>>> set([1,2,3]).issuperset(set([2,1]))
True 
>>>    
>>> set([1,2,3]).issuperset(set([3,5,9]))
False

3
Überlegen Sie, ob Sie Ihre Antwort richtig formatieren und eine Erklärung hinzufügen möchten.
Sam
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.