Seite 1 von 1

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

Verfasst: Montag 1. November 2021, 11:09
von alfer
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?

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

Verfasst: Montag 1. November 2021, 12:33
von Sirius3
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.

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

Verfasst: Montag 1. November 2021, 19:36
von __blackjack__
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()

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

Verfasst: Freitag 5. November 2021, 12:19
von alfer
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.

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

Verfasst: Freitag 5. November 2021, 12:57
von Sirius3
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)