Python 2: unterschiedliche Bedeutung des Schlüsselwortes 'in' für Mengen und Listen

8

Betrachten Sie dieses Snippet:

%Vor%

was zu:

führt %Vor%

Kann jemand erklären, warum das Stichwort 'in' für Mengen und Listen eine andere Bedeutung hat? Ich hätte erwartet, dass beide True zurückgeben, besonders wenn der Typ, der getestet wird, Gleichheitsmethoden definiert hat.

    
mskel 13.02.2012, 04:02
quelle

3 Antworten

15

Die Bedeutung ist die gleiche, aber die Implementierung ist anders. Listen prüfen einfach jedes Objekt und prüfen auf Gleichheit, damit es für Ihre Klasse funktioniert. Setzt die Objekte zuerst auf Hashwert, und wenn sie den Hash nicht richtig implementieren, scheint der Satz nicht zu funktionieren.

Ihre Klasse definiert __eq__ , definiert aber nicht __hash__ und funktioniert daher nicht ordnungsgemäß für Sätze oder als Schlüssel von Wörterbüchern. Die Regel für __eq__ und __hash__ besteht darin, dass zwei Objekte, die __eq__ als True haben, ebenfalls gleiche Hashes haben müssen. Standardmäßig basieren Objekte auf ihrer Speicheradresse. Ihre zwei Objekte, die nach Ihrer Definition gleich sind, liefern also nicht den gleichen Hash, also brechen sie die Regel über __eq__ und __hash__ .

Wenn Sie eine __hash__ -Implementierung angeben, funktioniert das problemlos. Für Ihren Beispielcode könnte es sein:

%Vor%     
Ned Batchelder 13.02.2012, 04:07
quelle
3

In fast jeder beliebigen Hashtabellen-Implementierung, einschließlich Pythons, müssen Sie die Hashing-Methode überschreiben, wenn Sie die Gleichheitsmethode überschreiben (in Python ist dies __hash__ ). Der Operator in für Listen überprüft nur die Gleichheit mit jedem Element der Liste, wobei der Operator in zuerst das gesuchte Objekt hasht, nach einem Objekt in diesem Slot der Hashtabelle sucht und dann auf Gleichheit prüft wenn sich etwas im Slot befindet. Wenn Sie also __eq__ außer Kraft setzen, ohne __hash__ zu überschreiben, können Sie nicht garantieren, dass der Operator in für Sets den richtigen Slot eincheckt.

    
Adam Mihalcin 13.02.2012 04:07
quelle
1

Definieren Sie die Methode __hash__() , die Ihrer Methode __eq__() entspricht. Beispiel .

    
jfs 13.02.2012 04:07
quelle

Tags und Links