String zu float?

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
heiliga horsd

Ich schäme mich gerade ein bisschen weil das Problem ziemlich trivial ist aber ich trotzdem zu blöd bin :oops:

Es geht um folgendes:

Code: Alles auswählen

>>>float(1/8)
0.125
Schön und gut, leider liegt mir 1/8 als String vor, was leider nicht so schön ist:

Code: Alles auswählen

>>>float('1/8')
ValueError: invalid literal for float(): 1/8
Was mach ich falsch?


Lg HH


P.S.: Ich will fractions wenn möglich meiden falls das jemand auf den Lippen hat
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Im einfachsten Falle einfach eval nehmen. Ist aber nicht sehr performant.
Andernfalls den String parsen, die Zeichen nach int oder float konvertieren und die math. Operation ausführen.
Im gezeigten Bsp. könnte man den String mit split('/') zerlegen.
heiliga horsd

Wie sähe das mit eval() aus? Außerdem is das doch ein wenig kritisch bzgl. Sicherheit oder?

Das mit dem Parsen ist IMHO keine so gute Idee, da da jeder beliebige mathematische (keine spezialsachen oder so, aber +-*/** sind durchaus möglich) Ausdruck oder auch nur eine Zahl stehen könnte.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Schau dir mal das ast-Modul an, damit sollte das recht schnell gehen. Ansonsten lassen sich mit der Suche auch noch einige kleine Parser für dieses Problem finden.

Sebastian
Das Leben ist wie ein Tennisball.
heiliga horsd

Danke dir!

Bin mal kurz drüber geflogen und habe ast.literal_eval() ausprobiert, leider funktioniert das bei 1/8 oder anderen mathematischen ausdrücken nicht, float(eval()) hingegen schon. Was muss ich denn bei float(eval()) beachten, damit das ganze wieder sicher wird?
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Wie wärs, wenn du einfach mal erzählen würdest, was du eigentlich genau machen willst. Ich habe den Eindruck dass du nicht einfach nur "1/8" in einen float umwandeln, sondern irgendwelche Mathematischen Ausdrücke auswerten willst.
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

heiliga horsd hat geschrieben:Wie sähe das mit eval() aus? Außerdem is das doch ein wenig kritisch bzgl. Sicherheit oder?

Code: Alles auswählen

x = eval('1/8')
Ich weiss nicht genau was Du exakt mit Sicherheit meinst, aber eval erwatet natürlich einen gültigen Python Ausdruck. Andernfalls kassierst Du eine Exception. Aber das ist im Grunde wie bei jedem anderen Python Code auch.
heiliga horsd

Es geht um ein Programm welches mit Wahrscheinlichkeiten arbeitet.
Die Wahrscheinlichkeiten werden in der Notation

P(<Ereignisname>) = <Wahrscheinlichkeit>

eingegeben. Den String teile ich intern in verschiedene Bereiche und den mathematischen Ausdruck (= <Wahrscheinlichkeit>) will ich auswerten und als float zwischenspeichern um später damit rechnen zu können.

@hendriks: Naja ich hab mal gehört eval sei unsicher, da es alles ausführt was man rein schiebt, also auch importe etc.

Lg HH
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

heiliga horsd hat geschrieben:Bin mal kurz drüber geflogen und habe ast.literal_eval() ausprobiert, leider funktioniert das bei 1/8 oder anderen mathematischen ausdrücken nicht
Dann solltest du vielleicht nicht nur mal kurz rüberfliegen, sondern dir das Modul mal richtig anschauen ;-)
heiliga horsd hat geschrieben:float(eval()) hingegen schon. Was muss ich denn bei float(eval()) beachten, damit das ganze wieder sicher wird?
Der beste Weg ist es, eval erst gar nicht zu verwenden.
Das Leben ist wie ein Tennisball.
heiliga horsd

EyDu hat geschrieben:
heiliga horsd hat geschrieben:Bin mal kurz drüber geflogen und habe ast.literal_eval() ausprobiert, leider funktioniert das bei 1/8 oder anderen mathematischen ausdrücken nicht
Dann solltest du vielleicht nicht nur mal kurz rüberfliegen, sondern dir das Modul mal richtig anschauen ;-)
OK, habe ich, aber bis auf das genannte ast.literal_eval() seh ich da nichts was mir konkret hilft... oder worauf willst du hinaus?
EyDu hat geschrieben:
heiliga horsd hat geschrieben:float(eval()) hingegen schon. Was muss ich denn bei float(eval()) beachten, damit das ganze wieder sicher wird?
Der beste Weg ist es, eval erst gar nicht zu verwenden.
Was bleibt mir (so wies momentan aussieht) anderes übrig? :(
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

Code: Alles auswählen

import ast

source = '16/8'
node = ast.parse(source, mode='eval')

print eval(compile(node, '<string>', mode='eval'))
damit erhälst du wenigstens den int Wert der Zahl. Aber mit ein bisschen suchen wird man dies auch als float schaffen...
heiliga horsd

Ich habe nun ein wenig im Forum rumgestöbert aber nichts außer eval gefunden, was mir floats aus mathematischen ausdrücken liefert (ich habe auch nach ast float gesucht aber nix brauchbares gefunden)

Ich werds bei eval belassen, danke an alle!
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

DaMutz, dein Ansatz ist leider auch nicht besser als direkt eval() zu benutzen. Dies ist IMMER gefährlich, da es nahezu beliebigen Code auszuführen erlaubt. Ich bin mir sicher, ich hatte hier schon mal einen auf dem ast-Modul basierenden Interpreter für mathematische Ausdrücke gepostet, doch ich finde ihn auf die Schnelle nicht. Vielleicht hilft http://python-forum.de/viewtopic.php?p=147406#p147406. So schwer ist es nicht, zu prüfen, dass nur gewünschte Operationen und keine Funktionen vorkommen und dann erst eval auf dem Ergebnis aufzurufen.

Stefan
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

das funktioniert (mit Python 2.6.):

Code: Alles auswählen

>>> from fractions import Fraction
>>> bruch = '1/8'
>>> erg = float(Fraction(bruch))
>>> erg
0.125
Funktioniert AFAIK genau so auch mit Python 3.x

Gruß, noisefloor
BlackJack

@noisefloor: Die Anforderung wurde aber mittlerweile auf Ausdrücke erweitert, die mindestens auch ``+``, ``-``, und ``*`` enthalten können.
heiliga horsd

Danke sma, ich werd mir deinen ansatz mal näher anschauen!

Lg HH
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

noch 'ne Frage: Sind die Zahlen, die bei dir vorkommen immer Ganzzahlen oder können das auch "Komma-Zahlen" sein?

Gruß, noisefloor
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich würde auch `fractions` benutzen.
heiliga horsd

das können auch Komma-Zahlen sein, aber ich werde darauf achten die vorher in Punkte zu wandeln
Antworten