Textdatei auslesen und in Array speichern

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.
BlackJack

@TheMerchant: Arbeite doch mal ein Python-Grundlagentuorial durch. Listen sind ein wichtiger Grunddatentypen, da sollte man mit umgehen können ohne nach Beispielen für eine solch simple Sache fragen zu müssen. Zumal /me ja schon beschrieben hat wie es geht und ich die Abkürzung mit der `list()`-Funktion erwähnt habe.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

TheMerchant hat geschrieben:... ich schnall das nicht.
Noch genauer kann und will ich es nicht erklären.

Ich habe dir zwei ultrasimple Codezeilen genannt und gesagt wo du sie in deinem Code einfügen musst. Wenn dir das zu hoch ist, dann solltest du dringend mal einen Blick ins Tutorial werfen. Wir versuchen hier sonst einem Blinden Farbe zu erklären und das kann nicht funktionieren.

Wenn ich deine Aussage "Eine Liste ... ein Array... wie auch immer" lese, dann komme ich mir vor, als wolltest du weder lernen noch überhaupt etwas erklärt bekommen, sondern uns nur als kostenlosen Programmierservice benutzen. Ich helfe ja gerne, aber die Nummer mache ich nicht mit.
TheMerchant
User
Beiträge: 18
Registriert: Montag 10. November 2014, 10:59

@/me:

Guten Morgen,
sorry wenn das so rübergekommen ist. Dies war nicht meine Absicht. Wenn das so rüber gekommen ist entschluldige ich mich dafür.

Sicher will ich lernen aber ich bin so ungeduldig weil ich mein "Projekt" fertig bekommen möchte und es "nur" an diesen Kleinigkeit hängt.
Was ich auf jeden fall nicht möchte ist ein Programmierservice.
Meine Aussage "Eine Liste ... ein Array... wie auch immer" war nur so gemeint dass der "Lösungsweg" ,ob eine Liste oder ein Array, mir egal ist.
Dies bezog sich nicht auf meine Einstellung.
Ich kann noch nicht einmal die Vor oder die Nachteile der beiden sagen. (Werde ich mir aber anschauen)

Ich werde mich ein wenig mehr in Gedult üben und mir deine Vorschläge zur Umsetzung nochmal genauer anschauen und weiter ausprobieren.

Gruß
TheMerchant
User
Beiträge: 18
Registriert: Montag 10. November 2014, 10:59

Hier das Ergebnis meine Recherche :

Code: Alles auswählen

import csv
METAR =[]
AIRPORT =[]
ICAO = []
with open("station.csv") as f:
    Metarliste = list(csv.reader(f))
    for i in range(0, len(Metarliste)):
        ICAO.append (Metarliste[i][0])
        AIRPORT.append (Metarliste[i][1])
        METAR.append (Metarliste[i][2])


print METAR[2]


# Mir ist klar geworden dass ich die Ergebnisse
# nicht in drei unterschiedliche Listen (ICAO,AIRPORT,METAR) verschieben muss.
# Aber ich denke dies ist für meine Programmablauf von Vorteil
Funktioniert so wie ich möchte. Bin aber auf das Trennzeichen von der CSV (";") "reingefallen".
Ich habe das Trennzeichen auf ein (",") zur Erstellung der CSV ungeändert.

Was haltet ihr von dem Code?
Würde das erstellen einer List auch mit dem (";") als Trennzeichen funktionieren.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Um über Einträge in einer Liste zu iterieren brauchst du nicht den Umweg über range und eine Ermittlung der Listenlänge zu gehen.

Code: Alles auswählen

data = ['alpha', 'beta', 'gamma']

# so nicht!
for i in range(0, len(data)):
    print(data[i])

# so passt es
for element in data:
    print(element)
Das ist deutlich handlicher und übersichtlicher.

Deine Frage mit dem ";" als Trennzeichen wurde in diesem Thread schon mehrmals beantwortet, aber du hattest da beim Lesen vermutlich noch ganz andere konzeptuelle Probleme. Du kannst beim Erstellen des CSV-Readers das gewünschte Trennzeichen mitgeben.
BlackJack

@TheMerchant: Man hätte hier nicht einmal zuerst in eine Liste anlegen müssen, weil wie schon gesagt das `reader`-Objekt iterierbar ist und die Datensätze aus der CSV-Datei liefert. Da kann man direkt mit einer ``for``-Schleife drüber iterieren.

Warum denkst Du das aufteilen auf die drei Listen wäre von Vorteil? Die Informationen gehören doch zusammen, also sollte man sie auch zusammen speichern damit man einfach auf zusammengehörende Werte zugreifen kann und die sich nicht aus drei Datenstrukturen zusammensuchen muss — am Ende gar wieder mit einem Index der nur nötig wird weil man die Daten aufgetrennt hat. Oder ohne Index in dem man die Daten wieder zusammenführt, aber dann stellt sich auch die Frage warum man die überhaupt erst aufgetrennt hat.

Auf Modulebene hat man üblicherweise nur Code der Konstanten, Funktionen, und Klassen definiert. Alles andere steckt in Funktionen. Das Hauptprogramm üblicherweise in einer die `main()` heisst und die wie folgt aufgerufen wird:

Code: Alles auswählen

if __name__ == '__main__':
    main()
Damit kann man das Modul als Programm ablaufen lassen, oder an anderer Stelle importieren *ohne* dass die `main()`-Funktion läuft. Zum Beispiel um einzelne Funktionen zu testen, manuell oder automatisiert, oder Teile des Moduls in anderen Modulen zu verwenden. Einige Werkzeuge, zum Beispiel zum Erzeugen von Dokumentation, erwarten ebenfalls das man ein Modul ohne Seiteneffekte importieren kann.

Namen komplett in Grossbuchstaben werden konventionell für Konstanten verwendet. Das trifft auf die Listen sicher nicht zu die Du aus einer sich regelmässig verändernden Datei mit Werten füllst.

Allgemeine Datentypen gehören nicht in Namen. Wenn man den Typ ändert müsste man auch den Namen überall ändern. Für Containertypen/Sequenztypen ist es üblich die Mehrzahl von dem zu verwenden wie man ein einzelnes Element nennen würde. Also zum Beispiel `parrots` wenn ein einzelnes Element mit dem Namen `parrot` treffend benannt wäre.

Edit: Das betrifft zum Beispiel auch `AIRPORT` denn dieser Name steht ja nicht für *einen* Flughafen(namen) sondern für mehrere, sollte also eher `airports` heissen (oder `airport_names`).
TheMerchant
User
Beiträge: 18
Registriert: Montag 10. November 2014, 10:59

@BlackJack:
Danke für den Tipp mit der Main. Werde dies in das Main Programm einbauen.
Habe beim erstellen der csv noch was geändert:

Code: Alles auswählen

with open(csv_filename, 'w') as csv_file:
w = Neuerstellung ;-)


@/me

Code: Alles auswählen

with open("station.csv") as f:
    Metarliste = list(csv.reader(f))
f.close
for element in Metarliste:
    print(element[0]) # ICAO
    print(element[1]) # Airportname
    print(element[2]) # Metar

print Metarliste # nur zum Testen ;-)

Muss ich eigendlich das File auch schliessen? so wie ich es gemacht habe?
Deine Frage mit dem ";" als Trennzeichen wurde in diesem Thread schon mehrmals beantwortet, aber du hattest da beim Lesen vermutlich noch ganz andere konzeptuelle Probleme. Du kannst beim Erstellen des CSV-Readers das gewünschte Trennzeichen mitgeben.
Das ich das Trennzeichen mitgeben kann habe ich herraus gefunden. Ich bin nur beim erstellen einer Liste darauf reigefallen dass eine Liste kein ";" als Trenner akzeptiert.
Habe dann das ";" durch ein "," ersetzt und schon hatte ich einen Zugriff auf die einzelnen Pos. der Liste.

Werde die nun mal in mein LCD.py einbauen und ausprobieren.
Danke für eure Hilfe
BlackJack

@TheMerchant: Dateien sollte man auch wieder schliessen. Das macht die ``with``-Anweisung, darum benutzt man die ja, weil die Datei auf jeden Fall geschlossen wird, egal aus welchem Grund der Codeblock verlassen wird, also auch bei Ausnahmen oder wenn man da zum Beispiel in einer Schleife mit einem ``break`` oder ``continue`` oder in einer Funktion mit einem ``return`` heraus springt.

Das ``f.close`` dagegen schliesst die Datei nicht, das hat so keinen Effekt, dazu hätte man die Methode auch *aufrufen* müssen: ``f.close()``.

Das Einlesen in einer Liste ist im Beispiel nur nötig weil Du die am Ende noch mal nur zum Testen ausgibst, sonst hätte man wie gesagt auch direkt über das `reader`-Objekt iterieren können.

Die Indexzugriffe in der Schleife kann man loswerden in dem man „tuple unpacking” (eigentlich „sequence unpacking”) verwendet und die drei Werte gleich an sprechende Namen bindet. Dann sind auch die Kommentare unnötig. Magische Indexzahlen sind halt nicht wirklich verständlich.

Klammern um ”Argumente” bei ``print`` sind bei Python 2 nicht nötig, sondern sogar sehr irreführend weil das keine Funktion ist, und sowie man mehr als ein ”Argument” hat, bedeutet das auch etwas völlig anderes und die Ausgabe ist sicher nicht das was eigentlich gewünscht war. Ungetestet:

Code: Alles auswählen

with open('station.csv') as station_file:
    metar_rows = list(csv.reader(station_file))

for icao, airport_name, metar_data in metar_rows:
    print icao
    print airport_name
    print metar_data
 
print metar_rows  # nur zum Testen ;-)
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Wenn man tatsächlich nur genau 3 Spalten hat, dann geht es auch einfacher.

Code: Alles auswählen

icao, airport_name, metar_data = zip(*metar_rows)
Demonstration am Beispiel.

Code: Alles auswählen

>>> data = [['a1', 'b1', 'c1'],
            ['a2', 'b2', 'c2'],
            ['a3', 'b3', 'c3'],
            ['a4', 'b4', 'c4']]
>>> foo, bar, baz = zip(*data)
>>> print(foo)
('a1', 'a2', 'a3', 'a4')
Anmerkung: Python 3, daher Klammern beim print.
BlackJack

@/me: Was hat denn das `zip()` jetzt gelöst? Das war doch gar nicht gefragt, oder habe ich was übersehen!?
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:@/me: Was hat denn das `zip()` jetzt gelöst? Das war doch gar nicht gefragt, oder habe ich was übersehen!?
Vielleicht habe ich ja auch etwas übersehen. Es schien mir, als sollten die einzelnen Spalten jeweils in eine eigene Datenstruktur zusammengefasst werden sollten. Wenn natürlich die Informationen grundsätzlich als weiter zusammengehörend betrachtet werden müssen, dann ist es in der Tat nicht sinnvoll die Daten in eine andere Struktur zu transformieren.

Gesetzt den Fall, dass die CSV-Daten in metar_rows eingelesen wurden reicht dann beispielsweise so etwas:

Code: Alles auswählen

def metars(data):
    for element in data:
        yield element[2]
    # Alternativ unter dem frischesten Python: yield from (element[2] for element in data)

for metar in metars(metar_rows):
    print(metar)
BlackJack

@/me: Der OP hat so etwas gemacht, aber ich habe das vehement in Frage gestellt weil die Daten ja letztendlich *zusammen* auf einem Display erscheinen sollen, dann müsste man die wieder zusammenfassen. Also warum erst trennen…
TheMerchant
User
Beiträge: 18
Registriert: Montag 10. November 2014, 10:59

@BlackJack
@/me

Hallo zusammen,
habe gestern abend alle Programmteile, wie ich es wollte, zum laufen gebracht.

Funktioniert einwandfrei!!!
Freue mich wie Bolle.

Wollte mich auf diesem Wege bei euch noch mal bedanken.
Mir spukt aber schon eine Verbesserung im kopf....

Werde ich mal am WE schaun ;-)

Danke
Gruß
Antworten