2016-08-15 6 views
1

Ich habe versucht, zwei Listen von Wörterbüchern zu vergleichen und die Benutzer-IDs von neuen Personen in list2 zu finden, die nicht in list1 sind. Zum Beispiel die erste Liste:Python - Listen von Wörterbüchern mit Tupeln vergleichen - unerwartetes Verhalten?

list1 = [{"userid": "13451", "name": "james", "age": "24", "occupation": "doctor"}, {"userid": "94324""name": "john", "age": "33", "occupation": "pilot"}] 

und die zweite Liste:

list2 = [{"userid": "13451", "name": "james", "age": "24", "occupation": "doctor"}, {"userid": "94324""name": "john", "age": "33", "occupation": "pilot"}, {"userid": "34892", "name": "daniel", "age": "64", "occupation": "chef"}] 

die gewünschte Ausgabe:

newpeople = ['34892'] 

Das ist, was ich zusammen stellen verwaltet:

list1tuple = ((d["userid"]) for d in list1) 
list2tuple = ((d["userid"]) for d in list2) 

newpeople = [t for t in list2tuple if t not in list1tuple] 

Dies scheint tatsächlich zu pret Die Listen, die ich verwende, könnten mehr als 50.000 Wörterbücher enthalten. Allerdings ist hier das Problem:

Wenn es eine Benutzer-ID in list2 findet, die tatsächlich nicht in list1 ist, fügt es es zu newpeople (wie gewünscht), , aber fügt dann auch alle anderen Benutzer-ID, die später in list2 zu newpeople kommt sowie.

Also, list2 enthält 600 userids und die 500. userid in list2 wird nirgends in list1 gefunden, das erste Element in newpeople ist die 500. Benutzer-ID (wieder wie gewünscht), gefolgt von den anderen 100 Benutzer-IDs das kam nach dem Neuen.

Das ist ziemlich verwirrend für mich - ich würde es sehr schätzen, wenn mir jemand helfen würde, zu verstehen, warum das passiert.

+0

list1tuple ist weder ein Tupel noch eine Liste, es ist ein Generator ...das ist dein Problem – donkopotamus

+0

@donkopotamus komischerweise genug, ich lief tatsächlich Typ (list1tuple) und bekam Generator, der mich noch mehr verblüffte. Würde es dir etwas ausmachen, mir in die Richtung zu zeigen, wie ich das beheben/mein Ziel erreichen könnte? danke –

+0

http://stackoverflow.com/questions/3462143/get-difference-between-tow-lists –

Antwort

3

Derzeit haben Sie gesetzt list1tuple und list2tuple als:

list1tuple = ((d["userid"]) for d in list1) 
list2tuple = ((d["userid"]) for d in list2) 

Dies sind Generatoren, keine Listen (oder Tupel), was bedeutet, dass sie nur einmal iteriert werden, was das Problem verursacht.

Sie könnten sie ändern Listen sein:

list1tuple = [d["userid"] for d in list1] 
list2tuple = [d["userid"] for d in list2] 

, die Sie über sie so oft wiederholen erlauben würde, wie Sie möchten. Aber eine bessere Lösung wäre, einfach sie setzt zu machen:

list1tuple = set(d["userid"] for d in list1) 
list2tuple = set(d["userid"] for d in list2) 

Und dann die eingestellte Differenz

newpeople = list2tuple - list1tuple 
+0

Das macht Sinn, danke! Frage: Ist das keine zusätzliche Klammer in list1tuple/list2tuple? –

1

Wie aus einer Python-Konsole, list1tuple zu sehen und list2tuple sind Generatoren:

>>> ((d["userid"]) for d in list1) 
<generator object <genexpr> at 0x10a9936e0> 

Obwohl der zweite Generator bleiben kann (es besteht keine Notwendigkeit, die Liste zu erweitern), sollte der erste zuerst in eine Liste, ein Set oder ein Tupel umgewandelt werden, zB:

list1set = {d['userid'] for d in list1} 
list2generator = (d['userid'] for d in list2) 

Sie können nun für die Mitgliedschaft in der Gruppe überprüfen:

>>> [t for t in list2generator if t not in list1set] 
['34892'] 
Verwandte Themen