Max() aus scientific notation

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
Stoli
User
Beiträge: 17
Registriert: Donnerstag 24. Oktober 2013, 21:02

Hallo miteinander,

ich bin noch ziemlich neu beim Programmieren mit Python bzw. sogar allgemein beim Programmieren :).

Ich habe allerdings ein Problem mit folgendem Beispiel:

Aus einer Datei, welche folgendermaßen aussieht:

Code: Alles auswählen

4.76473E-08
2.56745E-04
2.56544E-05
2.61648E-05
2.09209E-05
1.74740E-05
2.01370E-05
1.50030E-05
1.73485E-05
1.83673E-05
1.32169E-05
1.51459E-05
1.67822E-05
1.69395E-05
1.18044E-05
.
.
.
soll jetzt die größte Zahl gefunden werden. Leider kann ich mit max() nicht den richtigen Wert ermitteln, da Python die scientific notation einfach ignoriert und eine Zahl 9.2313E-10 als größte definiert.

Momentan sieht es so aus, auch habe ich einen Workarround gebildet und diese Zahlen als Dezimalzahlen dargestellt, das ist aber leicht umständlich und führt zu Rundungsfehlern. Gibts eine Alternative?

Code: Alles auswählen

f = open('Input.txt', 'r') 
data = f.readlines() 
for i in range(0,num_lines): # numlines mittels: ... num_lines = sum(1 for line in open('Input.txt')) ... ermittelt
	max(data)
print min(data)
Danke schonmal im Voraus :)

Gruß
Stoli
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Willkommen zur Programmierung, zu Python und natuerlich auch hier im Forum!

Zuerst: Das ist grausig. Was benutzt du denn zum lernen?

Zu deinem Problem: Nein, Python ignoriert die Exponenten-Schreibweise nicht, sondern sieht deine Daten nicht als Zahlen an. Zurecht, es sind ja auch Strings.

Hier eine kleine Session:

Code: Alles auswählen

In [9]: data = """4.76473E-08
2.56745E-04
2.56544E-05
2.61648E-05
2.09209E-05
1.74740E-05
2.01370E-05
1.50030E-05
1.73485E-05
1.83673E-05
1.32169E-05
1.51459E-05
1.67822E-05
1.69395E-05
1.18044E-05"""

In [10]: lines = data.split('\n')

In [11]: values = [float(v) for v in lines]

In [12]: min(values), max(values)
Out[12]: (4.76473e-08, 0.000256745)
`lines` hier entspricht deinem `data`.

Zum Ende noch: Deine `for`-Schleife ist ein Anti-Pattern in Python, man iteriert direkt ueber die Werte (siehe oben) nicht ueber den Umweg Indizes (was noch verschlimmert wird durch deine Art `num_lines` zu ermitteln). Dateien sollten geschlossen werden, entweder ueber `f.close()` nach `f.readlines()` oder direkt ueber das `with`-Statement.
Stoli
User
Beiträge: 17
Registriert: Donnerstag 24. Oktober 2013, 21:02

Hallo cofi,
danke für die Flotte antwort. Ich habe ein Buch "Python für Progammiereinsteiger" (ISBN-10: 3836217384). Außerdem benutze ich für code-schnippsel das Internet - was mir bewusst ist, dass das nicht immer die beste Lösung ist.

Ich habe wohl unterschlagen, dass die Datei endlich viele (aber sehr viele) Zeilen. Also muss bzw. will ich diese mit dem open() öffnen und nicht als Liste im Programm haben.

Okay, dass ich die Strings in Zahlen umwandeln muss ist mir jetzt bewusst.

Gibt's irgend einen Tipp wie ich es sonst lösen könnte?

Ich wil ein recht komplexes Tool aufbauen und mache hier viel mit Trial & Error..

Gruß
Stoli

EDIT:

für mich ist es auch möglich die einzulesende Datei in folgendem Format zu Speichern, wenn das etwas erleichtert?

Code: Alles auswählen

[4.76473E-082.56745E-042.56544E-052.61648E-052.09209E-05...usw
BlackJack

@Stoli: Eine Zeile pro Zahl ist schon ganz gut weil Dateiobjekte iterierbar sind und der Iterator dabei jeweils eine Zeile als Element betrachtet.

Das was Du haben möchtest lässt sich wie folgt realisieren: Das Dateiobjekt ist ein Iterator über Zeilen in der Datei. Die Elemente sind also Zeichenketten mit der Zahldarstellung. Mit `itertools.imap()` und `float()` kann man daraus einen Iterator über die Zahlen machen. `max()` kann als Argument einen Iterator mit Werten entgegennehmen. Damit hat man dann:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from itertools import imap


def main():
    with open('test.txt', 'r') as lines:
        maximum = max(imap(float, lines))
    print maximum


if __name__ == '__main__':
    main()
Stoli
User
Beiträge: 17
Registriert: Donnerstag 24. Oktober 2013, 21:02

Danke BlackJack! Das war das, was ich gesucht habe :)

Mein Tool soll aus mehreren Aufgabenteilen bestehen - wenn ich wieder an meine Grenzen komme werde ich mich nochmal melden :)

Viele Grüße
Stoli
Antworten