Seite 1 von 1

"in" Operator gibt komischerweise True zurück

Verfasst: Mittwoch 17. November 2004, 08:26
von leoel
Hallo!

Ist es eigentlich gewollt, dass folgende Abfrage True ergibt?

Code: Alles auswählen

print 1.0 in [1, 2, 3]
oder anders rum

Code: Alles auswählen

print 1 in [1.0, 2.0, 3.0]
verstehe nicht ganz, warum das so ist?

Mathematisch ist es klar (sowieso ;-) ), aber ich dachte immer, es wird ein Unterschied zw. 1 und 1.0 gemacht?

Oder werden da Python-intern nur die tatsächlichen Werte verglichen, was aber bei Fließkommazahlen ja bekanntlich zu Problemem führen kann.

Danke,
Leo

Verfasst: Mittwoch 17. November 2004, 09:38
von jens

Code: Alles auswählen

print 1.0000000000000001 in [1, 2, 3]
print 1.0000000000000001==1
ist beides True.... Wenn du eine Null weg nimmst ist es erst False :?:

Verfasst: Mittwoch 17. November 2004, 12:09
von mawe
Hi!

@leoel:
for x in ... verwendet ==, und das vergleicht die Werte:

Code: Alles auswählen

1.0 == 1   # -> True
Wenn Du False haben willst, versuch mal das:

Code: Alles auswählen

1.0 is 1
@jens:
Computer können Dezimalzahlen nicht mit beliebiger Genauigkeit darstellen:

Code: Alles auswählen

>>>1.0000000000000001
1.0
>>>1.000000000000001
1.000...0011
Gruß, mawe

Verfasst: Mittwoch 17. November 2004, 13:46
von Dookie
Vorsicht mit is!!!
is testet auf Identität der Objekte nicht auf Gleichheit von Wert und Typ.

Code: Alles auswählen

>>> a=1
>>> b=1
>>> print a is b
True

>>> a=123
>>> b=123
>>> print a is b
False

>>> a=125
>>> b=a
>>> print a is b
True

Erklährung: Der erste Fall gibt True zurück, weil die Integerwerte -5 bis 99 (in Python2.3) fix vordefiniert sind, so brauchen für diese sehr häufing z.B. als Indexe für Listen oder in Schleifen verwendeten Werte nicht jedesmal bei Verwendung neue Instanzen erstellt zu werden, was natürlich aufwändiger ist als auf die Vordefinierten Instanzen zuzugreifen.

Wenn man auf Wert und Type Testen will macht man das am Besten so:

Code: Alles auswählen

>>> a = 123
>>> b = 123
>>> print a == b and type(a) == type(b)
True

>>> a = 123.0
>>> b = 123
>>> print a == b and type(a) == type(b)
False
gefahrlos mit is getestet werden kann auf None, True und False!


Gruß

Dookie

Verfasst: Mittwoch 17. November 2004, 14:38
von mawe
Hi!

Danke für die Erklärung Dookie! Man lernt nie aus :D

Gruß, mawe

Verfasst: Mittwoch 17. November 2004, 15:03
von leoel
interessant, dass man sich auch bei solchen Grundlagen noch mitunter sehr den Kopf zerbrechen kann.

Habe jedenfalls vorher schon auf 1.0 == 1 getestet ==> True. Interessieren würde mich halt, wie es Python schafft (eben aufgrund der Dezimalproblematik) einen Float mit einem Integer erfolgreich (mathematisch gesehen) zu vergleichen..

Jedenfalls danke,


lg Leoel

Verfasst: Mittwoch 17. November 2004, 15:09
von Dookie
Hi loel,

Python sagt zum Float: "He Float, vergleich dich mal mit dem 1"
Float sagt: "ok, da musst mir das 1 erstmal in einen Float wandeln"
Float macht dann »1.0 - float(1)« und sagt: "He Python, da kommt Null bei raus! Also sind die beiden gleich"



Gruß

Dookie

Verfasst: Mittwoch 17. November 2004, 15:32
von mawe
Hey Dookie, was kommt als nächstes, ... Fingerpuppen? :D

Gruß, amüsierter mawe

Verfasst: Mittwoch 17. November 2004, 16:15
von Dookie
hehe 8)

Verfasst: Freitag 19. November 2004, 14:07
von Leonidas
Dookie hat geschrieben:Python sagt zum Float: "He Float, vergleich dich mal mit dem 1"
Float sagt: "ok, da musst mir das 1 erstmal in einen Float wandeln"
Float macht dann »1.0 - float(1)« und sagt: "He Python, da kommt Null bei raus! Also sind die beiden gleich"
Die Aussage würde in die Hall of Fame passen :)

Die Operatoren werden von den Typen implementiert, also spricht auch nichts dagegen, eine Bruchklasse zu schreiben, die auch ganz normal mit float verglichen werden kann. Das habe ich sogar mal gemacht.