"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.
Antworten
leoel
User
Beiträge: 36
Registriert: Dienstag 25. Mai 2004, 08:54
Wohnort: Graz

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: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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])

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

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

Mittwoch 17. November 2004, 14:38

Hi!

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

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

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

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

Mittwoch 17. November 2004, 15:32

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

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

Mittwoch 17. November 2004, 16:15

hehe 8)
[code]#!/usr/bin/env python
import this[/code]
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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
Antworten