Warum ist (numpy.nan, 1) == (numpy.nan, 1)?

8

Dabei ist numpy.nan nicht gleich numpy.nan und (float('nan'), 1) ist nicht gleich float('nan', 1) ,

%Vor%

Was könnte der Grund sein? Prüft Python zuerst, ob die IDs identisch sind? Wenn die Identität beim Vergleich von Elementen eines Tupels zuerst überprüft wird, warum wird dann nicht geprüft, wenn Objekte direkt verglichen werden?

    
satoru 03.06.2015, 08:40
quelle

4 Antworten

1

Wenn Sie zwei Objekte in einem Tupel Python vergleichen, prüfen Sie zuerst, ob sie identisch sind.

Beachten Sie, dass numpy.nan is numpy.nan , aber float('nan') is not float('nan') .

In Objects/tupleobject.c wird der Vergleich wie folgt durchgeführt:

%Vor%

Und in PyObject_RichCompareBool sehen Sie die Überprüfung auf Gleichheit:

%Vor%

Sie können dies anhand des folgenden Beispiels überprüfen:

%Vor%

Wenn Sie (a1, 1) == (a1, 1) versuchen, wird nichts gedruckt, während (a1, 1) == (a2, 1) __eq__ verwendet und unsere Nachricht ausgibt.

Probieren Sie jetzt a1 == a1 und sehen Sie, ob es Sie überrascht; P

    
satoru 03.06.2015, 08:47
quelle
6

Wenn Sie numpy.nan == numpy.nan eingeben, ist es numpy, das entscheidet, ob die Bedingung wahr ist oder nicht. Wenn Sie tuples vergleichen, überprüft Python nur, ob die Tupel die gleichen Objekte haben, die sie auch haben. Sie können numpy die Entscheidung treffen lassen, indem Sie die tuples in numpy -Arrays umwandeln.

%Vor%

Der Grund ist, wenn Sie == mit numpy Objekten aufrufen, rufen Sie die numpy Funktion __eq__() auf, die speziell nan != nan sagt, weil mathematisch nan unbestimmt ist (könnte irgendwas sein) Fühle das nan != nan . Aber wenn Sie == mit Tupeln machen, rufen Sie die Tupel __eq__() -Funktion auf, die sich nicht um Mathematik kümmert und nur interessiert, ob Python-Objekte gleich sind oder nicht. Im Fall von (float('nan'),1)==(float('nan'),1) wird False zurückgegeben, da jeder Aufruf von float('nan') Speicher an einer anderen Stelle zuweist, wie Sie dies mit float('nan') is float('nan') überprüfen können.

    
João Abrantes 03.06.2015 08:49
quelle
3

Containerobjekte können frei definieren, was Gleichheit für sie bedeutet, und für die meisten bedeutet das, dass eine Sache wirklich, wirklich wichtig ist:

%Vor%

Daher wird in Containern normalerweise eine id Prüfung vor einer __eq__ Prüfung durchgeführt.

    
Ethan Furman 03.06.2015 08:47
quelle
0

Tupel prüfen zuerst mit Identität und dann mit Gleichheit, wenn die Identität nicht übereinstimmt.

%Vor%

ist False , einfach weil eine andere Objektinstanz erstellt wird ... wenn Sie stattdessen:

%Vor%

Sie erhalten True auch, weil x == x False ist, aber x is x ist True.

Numpy numpy.nan ist eine statische Instanz und deshalb "funktioniert es nicht".

Als eine wilde Vermutung wird diese "Abkürzung" für die Überprüfung der Identität zuerst aus Leistungsgründen durchgeführt.

    
6502 03.06.2015 09:03
quelle

Tags und Links