2010-10-14 9 views
53

Ich fand, dass es Frage zusammenhängt, wie zumindest einen zu finden, wenn Element in einer Liste vorhanden ist:
How to check if one of the following items is in a list?Wie überprüfen Sie, ob alle folgenden Elemente in einer Liste enthalten sind?

Aber was ist die beste und pythonic Art und Weise, ob alle Elemente in einer Liste existiert zu finden?

durch die docs Suche fand ich diese Lösung:

>>> l = ['a', 'b', 'c'] 
>>> set(['a', 'b']) <= set(l) 
True 
>>> set(['a', 'x']) <= set(l) 
False 

Andere Lösung sein würde:

>>> l = ['a', 'b', 'c'] 
>>> all(x in l for x in ['a', 'b']) 
True 
>>> all(x in l for x in ['a', 'x']) 
False 

Aber hier müssen Sie mehr Tipp tun.

Gibt es noch andere Lösungen?

+4

Was ist los mit 'set (kleiner) <= set (größer)'? – eumiro

Antwort

42

Operatoren wie <= in Python sind in der Regel nicht überschrieben, etwas anderes als "weniger als oder gleich ". Es ist ungewöhnlich für die Standard-Bibliothek tut dies - es riecht nach Legacy-API für mich.

Verwenden Sie die äquivalente und deutlichere Methode set.issubset. Beachten Sie, dass Sie das Argument nicht in eine Menge konvertieren müssen. Es wird das für Sie tun, wenn es nötig ist.

set(['a', 'b']).issubset(['a', 'b', 'c']) 
+2

wusste nicht, dass Sie die Liste direkt als Argument an issubset übergeben könnten ... schön! – tsimbalar

+0

Während ich mit der Stimmung einverstanden bin, bin ich ziemlich OK mit der Idee von '<=' und 'issubset', die dasselbe bedeuten. Warum magst du es nicht? –

+2

@Just: In erster Linie, weil es nicht offensichtlich ist, was '<=' für eine Menge bedeutet, ohne entweder in den Dokumenten nachzuschauen oder vorher zu wissen, was es in der Mengenlehre bedeutet, während jeder weiß, was "subset" automatisch bedeutet. –

49

Ich würde wahrscheinlich set auf folgende Weise verwenden:

set(l).issuperset(set(['a','b'])) 

oder andersrum:

set(['a','b']).issubset(set(l)) 

Ich finde es ein bisschen besser lesbar, aber es kann über-kill sein. Sätze sind besonders nützlich, um Union/Schnittpunkt/Unterschiede zwischen Sammlungen zu berechnen, aber es ist möglicherweise nicht die beste Option in dieser Situation ...

+0

Tatsächlich sind 'MySet.issubset (MyOtherSet)' und 'MySet <= MyOtherSet' identisch. – Wok

+1

@wok: Oh, ich wusste das nicht, aber ich denke, die <= Syntax ist ein wenig verwirrend, da eine ähnliche Syntax mit Listen verwendet werden kann, aber mit einer ganz anderen Bedeutung. – tsimbalar

+2

Es ist nicht wirklich so verwirrend, wenn Sie sich daran erinnern, dass die Inklusion eine Teilaufordnung für eine Menge von Sätzen definiert.Es ist eigentlich etwas verwirrend, dass '<=' die Bedeutung hat, die es für Sequenzen hat: man könnte erwarten, dass es bedeutet "ist eine Subsequenz" statt lexikographischer Ordnung. – aaronasterling

4

Ich mag diese beiden, weil sie die logischste scheinen, letztere kürzer und wahrscheinlich am schnellsten (hier gezeigt mit neuen Set-Literale, die backported zu Python waren 2.7):

all(x in {'a', 'b', 'c'} for x in ['a', 'b']) 
# or 
{'a', 'b'}.issubset({'a', 'b', 'c'}) 
1

Was, wenn Ihr Listen enthalten folgende Duplikate:

v1 = ['s', 'h', 'e', 'e', 'p'] 
v2 = ['s', 's', 'h'] 

Sätze enthalten keine Duplikate. Die folgende Zeile gibt also True zurück.

set(v2).issubset(v1) 

Um Duplikate zu zählen, können Sie den Code verwenden können:

v1 = sorted(v1) 
v2 = sorted(v2) 


def is_subseq(v2, v1): 
    """Check whether v2 is a subsequence of v1.""" 
    it = iter(v1) 
    return all(c in it for c in v2) 

Also, die folgende Zeile gibt False zurück.

is_subseq(v2, v1) 
Verwandte Themen