"in" Operator gibt komischerweise True zurück

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
leoel
User
Beiträge: 36
Registriert: Dienstag 25. Mai 2004, 08:54
Wohnort: Graz

"in" Operator gibt komischerweise True zurück

Beitragvon leoel » Mittwoch 17. November 2004, 08:26

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
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Mittwoch 17. November 2004, 09:38

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 :?:
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Beitragvon mawe » Mittwoch 17. November 2004, 12:09

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
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Mittwoch 17. November 2004, 13:46

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

Code: Alles auswählen

#!/usr/bin/env python
import this
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Beitragvon mawe » Mittwoch 17. November 2004, 14:38

Hi!

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

Gruß, mawe
Benutzeravatar
leoel
User
Beiträge: 36
Registriert: Dienstag 25. Mai 2004, 08:54
Wohnort: Graz

Beitragvon leoel » Mittwoch 17. November 2004, 15:03

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
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Mittwoch 17. November 2004, 15:09

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
Zuletzt geändert von Dookie am Mittwoch 17. November 2004, 16:18, insgesamt 1-mal geändert.

Code: Alles auswählen

#!/usr/bin/env python
import this
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Beitragvon mawe » Mittwoch 17. November 2004, 15:32

Hey Dookie, was kommt als nächstes, ... Fingerpuppen? :D

Gruß, amüsierter mawe
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Mittwoch 17. November 2004, 16:15

hehe 8)

Code: Alles auswählen

#!/usr/bin/env python
import this
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Freitag 19. November 2004, 14:07

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder