2013-02-28 27 views
14

Ich habe zwei Listen sagenWie überprüft man, ob alle Einträge in einer Liste in einer anderen Liste stehen?

List1 = ['a','c','c'] 
List2 = ['x','b','a','x','c','y','c'] 

Jetzt möchte ich, wenn alle Elemente von Liste1 dort in List2 sind, um herauszufinden. In diesem Fall sind alle da. Ich kann die Teilmengenfunktion nicht verwenden, da ich in Listen wiederholte Elemente haben kann. Ich kann eine for-Schleife verwenden, um die Anzahl der Vorkommen jedes Elements in List1 zu zählen und festzustellen, ob sie kleiner oder gleich der Anzahl der Vorkommen in List2 ist. Gibt es einen besseren Weg, dies zu tun?

Danke.

Antwort

25

Sie können immer noch die Teilmenge Funktionalität verwenden, indem Sie einen Satz on the fly zu erstellen:

>>> list1 = ['a', 'c', 'c'] 
>>> list2 = ['x', 'b', 'a', 'x', 'c', 'y', 'c'] 
>>> set(list1) < set(list2) 
True 

Oder wenn Sie, wenn die Anzahl von Vorkommnissen überprüfen möchten entspricht, können Sie die Verwendung des Zählertyp machen und definieren Ihre eigene Untergruppe Beziehung:

>>> from collections import Counter 
>>> def counterSubset(list1, list2): 
     c1, c2 = Counter(list1), Counter(list2) 
     for k, n in c1.items(): 
      if n > c2[k]: 
       return False 
     return True 

>>> counterSubset(list1, list2) 
True 
>>> counterSubset(list1 + ['a'], list2) 
False 
>>> counterSubset(list1 + ['z'], list2) 
False 

Wenn Sie bereits Zähler haben (was eine nützliche Alternative Ihre Daten sein könnte sowieso speichern), können Sie dies auch als eine einzige Zeile schreiben Sie einfach:

+0

Hallo, der zweite Teil ist was ich versucht habe zu tun. Es sieht so aus, als ob es der einzige Weg ist. Vielen Dank! – pogo

+0

Scheitert es bei '['s', 'e', ​​'r', '', '', '', 'y']' und '['', '', '', 'y' ] ' – SIslam

+0

@SIslam Hängt von der Bestellung ab. Die zweite Liste ist eine Teilmenge der früheren Liste, so dass die Lösung in meiner Antwort sie korrekt erkennen würde. – poke

0

Dies wird return true ist alle Elemente in Liste1 in List2 sind

def list1InList2(list1, list2): 
    for item in list1: 
     if item not in list2: 
      return False 
    return True 
+1

Ich bin nicht der Downvoter, aber Sie sollten sich wirklich [PEP 8] (http://www.python.org/dev/peps/pep-0008/) ansehen. Ihre 'if'-Syntax ist deaktiviert, Sie haben ein nicht benötigtes Semikolon, und Ihr Variablennamenstil sollte für Klassen reserviert sein. –

+1

Dies kann auch auf eine einzige Zeile reduziert werden: 'all (Element in Liste2 für Element in Liste1)'. –

+0

Ich habe List1 und List2 als Variablennamen verwendet, weil das in der Frage war, und es ist eine Weile her, seit ich Python benutzt habe, also gebe ich die Semikolons und Klammern um die If waren meine schlechten – jeffam217

1
def check_subset(list1, list2): 
    try: 
     [list2.remove(x) for x in list1] 
     return 'all elements in list1 are in list2' 
    except: 
     return 'some elements in list1 are not in list2' 
2

Beachten Sie, die folgenden Möglichkeiten:

>>>listA = ['a', 'a', 'b','b','b','c'] 
>>>listB = ['b', 'a','a','b','c','d'] 
>>>all(item in listB for item in listA) 
True 

Wenn Sie lesen die "alle" -Linie, wie Sie wäre in Englisch, das ist nicht falsch, aber kann irreführend sein, da listA ein drittes 'b' hat, aber listB nicht.

Dies hat auch das gleiche Problem:

def list1InList2(list1, list2): 
    for item in list1: 
     if item not in list2: 
      return False 
    return True 

einfach eine Anmerkung. Folgendes funktioniert nicht:

>>>tupA = (1,2,3,4,5,6,7,8,9) 
>>>tupB = (1,2,3,4,5,6,6,7,8,9) 
>>>set(tupA) < set(TupB) 
False 

Wenn Sie die Tupel in Listen konvertieren, funktioniert es immer noch nicht. Ich weiß nicht, warum Streicher funktionieren, aber Intars nicht.

Works hat aber gleiches Problem von nicht Zahl des Elemente Vorkommen zu halten:

>>>set(tupA).issubset(set(tupB)) 
True 

Verwendung von Sets ist keine umfassende Lösung für Multi-Element-Matching-Auftreten.

Aber hier ist eine Einzeiler Lösung/Anpassung an shantanoo Antwort ohne try/except:

all(True if sequenceA.count(item) <= sequenceB.count(item) else False for item in sequenceA) 

Eine eingebaute Funktion eine Liste Verständnis unter Verwendung eines ternären Konditionaloperator wickeln. Python ist großartig! Beachten Sie, dass "< =" nicht "==" sein sollte.

Mit dieser Lösung Sequenz A und B kann Typ Tupel und Liste und andere "Sequenzen" mit "zählen" Methoden. Die Elemente in beiden Sequenzen können die meisten Typen sein. Ich würde das nicht mit Diktaten verwenden, wie es jetzt ist, daher verwende ich "Sequenz" statt "iterierbar".

Verwandte Themen