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
Nick Heiner
quelle

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.

danben
quelle
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
ChristopheD
quelle
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
Artem Skoretskiy
quelle
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
Eugene Yarmash
quelle
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
Jordan Stefanelli
quelle
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
Bobin Motti Thomas
quelle
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
Mamata
quelle
3
Überlegen Sie, ob Sie Ihre Antwort richtig formatieren und eine Erklärung hinzufügen möchten.
Sam