String in Float umwandeln - egal ob Beistrich oder Punkt

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
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi all!

Ich habe mich heute gefragt, ob es dafür eine eingebaute Funktion gibt:
Es soll, egal in welcher Art der String formatiert wurde, daraus ein Float werden. Man kann davon ausgehen, dass entweder der Punkt oder das Komma als Dezimaltrennzeichen verwendet wird. Wenn die Konvertierung nicht sicher vorgenommen werden kann, dann sollten die Ländereinstellungen herangezogen werden. Wenn es keine Funktion dafür gibt, wie würdet ihr das programmieren, sodass die Funktion immer noch schnell läuft? :wink:

Code: Alles auswählen

1,000.01 --> 1000.01
1.000,01 --> 1000.01
1000,01 --> 1000.01
1000.01 --> 1000.01
123.123 --> 123123 (Ländereinstellung verwenden?) --> nachkorrigiert; danke Dookie
1,001 --> 1001 (Ländereinstellung verwenden?)
1.001 --> 1001 (Ländereinstellung verwenden?)
123.123,010 --> 123123.01
1,000.00123 --> 1000.00123
1.000,00123 --> 1000.00123
usw.
Ergänzung (nachträglich hinzugefügt):

Code: Alles auswählen

1 --> 1.0
1000 --> 1000.0
soll natürlich auch richtig erkannt werden.


lg
Gerold
:-)
Zuletzt geändert von gerold am Samstag 2. Oktober 2004, 10:15, insgesamt 2-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi gerold,

woran erkennst Du bei Deinen Beispielen bei 123.123 --> 123123 daß der Punkt kein Komma sondern der Tausenderseperator ist? Drei Zeilen darunter 123.123,010 --> 123123.01 ist das Komma ein Komma obwohl auch hier noch drei Stellen nach dem Komma kommen!

Für Umwandlungen, die die localen Einstellungen berücksichtingen gibts das Modul locale

ansonst mit einer Funktion, die aber nur Zahlen mit einem Komme (egal ob Punkt oder Komma) umwandelt:

Code: Alles auswählen

def str_to_float(s):
    commapos = max(s.rfind("."), s.rfind(","))
    return float(s[:commapos].replace(".","").replace(",","") +
                 "." + s[commapos+1:])

Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi Dookie!

Auch noch so spät wach... :wink:
Dookie hat geschrieben:woran erkennst Du bei Deinen Beispielen bei 123.123 --> 123123 daß der Punkt kein Komma sondern der Tausenderseperator ist?
Du hast recht, bei diesem Beispiel erkennt man nicht ob Tausenderpunkt oder Dezimalzeichen. Ich habe es nachkorrigiert.
Dookie hat geschrieben:Drei Zeilen darunter 123.123,010 --> 123123.01 ist das Komma ein Komma obwohl auch hier noch drei Stellen nach dem Komma kommen!
Hier ist der Fall eindeutig. In diesem Beispiel gibt es einen Punkt und einen Beistrich. Das äußerst rechts stehende Zeichen ist folglich das Dezimalzeichen.
Dookie hat geschrieben:Für Umwandlungen, die die localen Einstellungen berücksichtingen gibts das Modul locale
Leider kann/möchte ich nicht davon ausgehen, dass diese Strings sich an die lokalen Einstellungen halten. Deshalb dachte ich, dass nur dann, wenn aus dem String nicht eindeutig hervorgeht, welche Zahl damit gemeint ist, die Locales herangezogen werden. Der Computer soll sich um alles kümmern. Man könnte doch an die Funktion ein Argument übergeben, welches der Funktion mitteilt, was sie im Zweifelsfall tun soll. - - Sollen die Locales herangezogen werden?
- Soll eine Exception ausgelöst werden?
- Soll ein Standardwert zurück gegeben werden?
- Soll ein Standard-Trennzeichen angenommen werden?
Dookie hat geschrieben:ansonst mit einer Funktion, die aber nur Zahlen mit einem Komme (egal ob Punkt oder Komma) umwandelt:

Code: Alles auswählen

def str_to_float(s):
    commapos = max(s.rfind("."), s.rfind(","))
    return float(s[:commapos].replace(".","").replace(",","") +
                 "." + s[commapos+1:])

So wie ich diese Funktion sehe, geht sie immer davon aus, dass das äußerst rechts vorkommende Zeichen ein Dezimaltrennzeichen ist und dass immer ein Dezimaltrennzeichen vorkommt, was nicht immer der Fall sein kann. Leider liefert str_to_float("100") die Zahl 10.1 zurück.


lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mahlzeit gerold,

jo bei meinem Beispiel steht ja auch ausdrücklich daß ein Komma vorkommen muss egal ob als Punkt oder Komma.
Sicher kann man auch alle möglichen Spezialfälle abdecken, wenn Du dann bei 10000 Codezeilen angelangt bist, wirds wohl nichts mehr mit einer schnellen Umwandlung die du ja möchtest. :wink:

Woher werden denn die Zahlen genommen, bzw. wie werden die eingegeben? Eventuell könnte man schon hier eingreifen um zu einer einfach umwandelbaren Darstellung zu gelangen.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Dookie hat geschrieben:wenn Du dann bei 10000 Codezeilen angelangt bist, wirds wohl nichts mehr mit einer schnellen Umwandlung die du ja möchtest. :wink:
Woher werden denn die Zahlen genommen, bzw. wie werden die eingegeben?
Hi Dookie!

Mir geht es hier hauptsächlich darum, eine Funktion zu erstellen, die man in irgendeine Bibliothek (Modul) aufnehmen kann. Ich stelle mir das als nützliches Feature vor, falls es so eine Funktion noch nicht gibt.

Möglicher Einsatz für so eine Funktion:
- Übernahme von Zahlen aus einer Website. Da weiß ich ja nicht, welche Ländereinstellung der User hat.
- Liste von Zahlen, die vom Benutzer zu erstellen ist, in ein Programm zu übernehmen. --> Den Computer den Job machen lassen ohne immer sofort den Benutzer mit Meldungen zuschütten.
- ...

Ich schreibe später weiter... muss jetzt essen gehen. ;-)

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi gerold,

im Prinzip bräuchtest du einen Mustererkennungsalgorithmus, der erkennt ob eine Zeichenfolge eine Zahl (mit oder ohne) Komma und Tausenderseperator ist. Hier müsste der Algo, bei dem Beispiel der Webseite am besten alle auf der Seite vorkommenden Zahlen analysieren um Zweifelsfälle zu behandeln. Ob sich der Aufwand wirklich lohnt scheint mir zweifelhaft, in den 20 Jahren, die ich mich jetzt mit Programmierung beschäftige, hätte ich so eine Funktion noch nie gebraucht.

Hier noch eine etwas robustere Version meines Scripts:

Code: Alles auswählen

def str_to_float(s):
    commapos = max(s.rfind("."), s.rfind(","))
    if commapos < 0: # kein "." und kein ","
        return float(s)
    return float(s[:commapos].replace(".","").replace(",","") +
                 "." + s[commapos+1:]) 
Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Antworten