Zeilen aus CSV mit Datum und Betrag einfüllen, wenn nötig

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
alfer
User
Beiträge: 8
Registriert: Samstag 16. Oktober 2021, 16:54

Guten Morgen,

Ich habe folgendes Problem / Denkfehler. Ich will aus einer CSV Datei die Beträge von fünf Datums (aus fünf Zeilen) auslesen und überprüfen. Dieser Code funktioniert so weit:

Code: Alles auswählen

import csv

file = open("C:/summen.csv", "r")

for line in file:
    for line in file:
        splitted = (line.strip().split(";"))
        if splitted[0] == "Zahltag":
              continue          
        if splitted[0] == "2020-12-31":
            y5 = splitted[0]
            d5 = splitted[1]
        elif splitted[0] == "2019-12-31":
            y4 = splitted[0]
            d4 = splitted[1]
        elif splitted[0] == "2018-12-31":
            y3 = splitted[0]
            d3 = splitted[1]
        elif splitted[0] == "2017-12-31":
            y2 = splitted[0]
            d2 = splitted[1]
        elif splitted[0] == "2016-12-31":
            y1 = splitted[0]
            d1 = splitted[1]
            
betrag = [y5,d5,y4,d4,y3,d3,y2,d2,y1,d1]
            
print(betrag)
Jetzt kann es aber sein das nur 3 Zeilen vorhanden sind, z.B. so:

Code: Alles auswählen

2019-12-31 0.25 => y4,d4
2018-12-31 0.00 => y3,d3
2017-12-31 0.24 =>y2,d2
Ich möchte gern das Python die fehlenden Daten durch ein festes Datum und den Betrag 0 ersetzt. Also im Beispiel:

Code: Alles auswählen

2020-12-31 0 =>y5,d5
2016-12-31 0 =>y1,d1
Es kann aber sein das es auch Jahre sind. Bedingungen sind das immer mindestens eine Zeile in der CSV steht und maximal fünf. Jemand eine Idee wie ich das hin bekomme?
Sirius3
User
Beiträge: 18278
Registriert: Sonntag 21. Oktober 2012, 17:20

Dateien öffnet nun mit dem with-Statement. Die doppelte for-Schleife ist Quatsch. CSV-Dateien liest man am besten mit dem csv-Modul. Statt durchnummerierten Variablennamen benutzt man passende Datenstrukturen. Hier z.B. ein Wörterbuch, dann kannst Du fehlende Einträge ganz leicht herausfinden.
Benutzeravatar
__blackjack__
User
Beiträge: 14076
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ein `collections.defaultdict` wäre vielleicht auch praktisch.

Code: Alles auswählen

#!/usr/bin/env python3
import csv
from collections import defaultdict


def main():
    with open("C:/summen.csv", "r", encoding="utf-8", newline="") as file:
        rows = csv.reader(file, delimiter=";")
        next(rows)  # Skip header.
        date_to_amount = defaultdict(int)
        date_to_amount.update(
            (row[0], int(row[1])) for row in rows if row[0] != "Zahltag"
        )

    print(
        [
            (date, date_to_amount[date])
            for date in (f"{year:04d}-12-31" for year in range(2016, 2021))
        ]
    )


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
alfer
User
Beiträge: 8
Registriert: Samstag 16. Oktober 2021, 16:54

Danke für die Denkanstöße. Ich habe es mit setdefault selbst hinbekommen:

Code: Alles auswählen

with open('C:/summen.csv', mode='r') as inp:
        reader = csv.reader(inp, delimiter=";")
        dict_from_csv = {rows[0]:rows[1] for rows in reader}
        dict_from_csv.setdefault("2020-12-31",0.0)
        dict_from_csv.setdefault("2019-12-31",0.0)
        dict_from_csv.setdefault("2018-12-31",0.0)
        dict_from_csv.setdefault("2017-12-31",0.0)
        dict_from_csv.setdefault("2016-12-31",0.0)
    
print(dict_from_csv)
Sortieren hat dann mit pandas super funktioniert. Macht jetzt genau was ich wollte. Vielen Dank nochmal.
Sirius3
User
Beiträge: 18278
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt fast gleichlautenden Code zu kopieren und leicht zu ändern, benutzt man eine Schleife.
`dict_from_csv` ist ein schlechter Variablennamen. Typen sollten nicht im Namen vorkommen, und dass die Daten irgendwann einmal vielleicht aus einer csv-Datei stammten, interessiert niemanden, sondern das wichtige ist, was für Daten in dieser Variable gespeichert sind, also z.B. das date_to_amount wie es __blackjack__ genannt hatte.
Die for-Schleife geht über eine row und nicht über mehrere rows.
Statt hinterher das Wörterbuch zu füllen, würde ich es davor machen:

Code: Alles auswählen

date_to_amount = dict.fromkeys(('%04d-12-31' %y for y in range(2016,2021)), 0)
with open('C:/summen.csv', mode='r') as file:
    reader = csv.reader(file, delimiter=";")
    date_to_amount.update(row[0]: row[1] for row in reader)
Antworten