2012-03-27 7 views
4

Ich bin ziemlich neu in Python, so begrüße ich alternative Ansätze.Wie kann ich einen benutzerdefinierten Vergleicher für das Schlüsselwort "in" in Python angeben?

Ich habe eine Liste von Wörterbüchern, mit denen ich beginne (aus einer Datei lesen). Jetzt habe ich eine Reihe zusätzlicher Wörterbücher, die ich dieser Liste hinzufügen möchte, aber nur, wenn sie nicht in der ursprünglichen Liste enthalten sind.

Ich fordere jedoch, dass "nicht in der ursprünglichen Liste" durch eine benutzerdefinierte Vergleichsfunktion definiert wird, und nicht, was auch immer Python als Standard verwendet.

Genauer gesagt möchte ich bestimmte Schlüssel/Wert-Paare im Wörterbuch vergleichen, und wenn sie gleich sind, geben Sie "True" für den Ausdruck zurück.

myList = ReadFromFile... 
newList = ReadFromFile... 
for item in newList: 
    if item not in myList: #I want custom behavior for this "in" 
     myList.append(item) 

Antwort

9

Verwendung any:

any(customEquals(item, li) for li in myList) 

Wenn myClass von einer Art ist, die Sie steuern können, können Sie auch die __contains__ Methode überschreiben.

+0

'customComparison' wahrscheinlich eine Lambda sein könnte, auch wenn es kurz genug ist. – jpm

+0

Es gibt immer noch eine Schleife in diesem 'any'. Wenn Sie also für jedes Element in' newList' das 'any' machen müssen, ist dies immer noch ein O (m * n) -Algorithmus. –

2

Sie nicht. Der Operator in ist Teil der Sprachsyntax. Was Sie tun möchten, ist so etwas wie dieses:

def comparison(item, otherContainer): 
    # Code here for custom comparison. 
    return True or False 

for item in NewList: 
    if not comparison(item, myList): 
    myList.append(item) 
+0

Gibt es einen schneller als m * n Weg, dies sauber in Python zu tun (dh ohne meinen eigenen Algorithmus zu implementieren)? – merlin2011

+0

@ merlin2011 - Es sei denn, es gibt einen Mechanismus in Ihrer Vergleichsfunktion, der einige der Überprüfungen überflüssig macht. Sonst ist 'm * n' so gut wie du bekommen wirst. –

1

um Ihren Kommentar zu gddc Antwort Adresse:

Wenn Ihre Werte hashable sind (grob gesprochen, das heißt, sie sind unveränderlich), die effizienteste ist wahrscheinlich, Pythons Sets zu benutzen. Nach dem Einlesen in myList, generieren Sie eine Menge der Werte von Interesse von myList. (Wenn ich Ihre Frage richtig lese, haben Sie eine Reihe von Tupeln, die von myList erzeugt werden.) Wenn Sie dann über newList laufen, können Sie die Mitgliedschaft (wiederum der interessierenden Werte) für diese Menge testen, die O ist (1) pro Test, was eine algorithmische Komplexität von O (m + n) ergibt.

Sie können operator.itemgetter verwenden, um die Werte von Interesse zu greifen.

+0

Ich will nicht pedantisch sein - ich bin wirklich neugierig: Zitat: "grob gesagt, das bedeutet, sie sind unveränderlich" Wie würden Sie in der Lage sein, ein veränderliches zu hacken? – inspectorG4dget

+2

@inspectorG4dget: Sie würden nicht. Ein veränderbares Objekt ist niemals hashbar. Aber ein * sogenanntes * unveränderliches Objekt ist nicht immer hashbar. Wir bezeichnen Tupel (zum Beispiel) oft als "unveränderlich". Aber wirklich, sie sind nur oberflächlich unveränderlich. Ein Tupel kann eine Liste enthalten, und diese Liste ist änderbar, wodurch das Tupel nicht mehr abgespeichert werden kann. Ein Tupel von ganzen Zahlen wäre immer noch hashbar. –

1

Wenn Sie eine Funktion vom Typ (object, object) --> bool müssen, die für die Eindämmung testet, gibt es bereits one in the standard lib:

from operator import contains 

myList = ReadFromFile... 
newList = ReadFromFile... 
for item in newList: 
    if not contains(myList, item): 
     myList.append(item) 
Verwandte Themen