Menu

Python-CSV: CSV-Dateien mit dem csv-Modul lesen und schreiben

Wie du CSV-Dateien in Python liest und schreibst — das csv-Modul, DictReader und DictWriter, Header, Quoting und wann du stattdessen zu pandas greifst.

CSV ist einfacher, als es aussieht (und kniffliger, als du erwartest)

Eine CSV-Datei ist nur Text: Zeilen getrennt durch Zeilenumbrüche, Felder getrennt durch Kommas. Das ist die Idee. In der Praxis triffst du auf zitierte Strings mit Kommas darin, Felder mit eingebetteten Zeilenumbrüchen, verschiedene regionale Konventionen (Komma vs. Semikolon), aus Excel gespeicherte Dateien mit BOM — genug Randfälle, dass ein eigenes line.split(",") fast immer ein Fehler ist.

Pythons eingebautes csv-Modul kümmert sich darum. Für kleine bis mittlere Dateien brauchst du selten mehr.

Eine CSV mit csv.reader lesen

csv.reader liefert jede Zeile als Liste von Strings:

import csv

with open("people.csv", newline="") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

Ein paar nicht offensichtliche Details:

  • Übergib immer newline="" an open. Das csv-Modul kümmert sich selbst um Zeilenendungen; ohne diese Option bekommst du unter Windows zusätzliche Leerzeilen.
  • Jeder Wert ist ein String. "42" bleibt ein String, bis du int(...) aufrufst. CSV hat keine Typen.
  • Die Headerzeile ist einfach eine weitere Zeile. Hat deine Datei Header, überspring die erste Zeile manuell oder wechsel zu DictReader.

Die Headerzeile überspringen

import csv

with open("people.csv", newline="") as f:
    reader = csv.reader(f)
    headers = next(reader)         # pulls the first row out
    for row in reader:
        print(row)

next(reader) bewegt den Iterator um eins und gibt diese Zeile zurück.

Als Dicts mit DictReader lesen

csv.DictReader behandelt die erste Zeile als Header und gibt jede nachfolgende Zeile als Dict:

import csv

with open("people.csv", newline="") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"], row["email"])

Das ist fast immer, was du willst. Spaltennamen sind selbsterklärend, und das Umsortieren von Spalten in der Quelle bricht deinen Code nicht.

Hat die Datei keine Header, übergib sie explizit mit fieldnames=["name", "email", ...].

Eine CSV mit csv.writer schreiben

csv.writer verwandelt Zeilen (Listen) in CSV-Zeilen:

import csv

rows = [
    ["name", "age", "city"],
    ["Rosa", 30, "Lisbon"],
    ["Ada", 36, "London"],
]

with open("out.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(rows)

writerow(row) schreibt eine einzelne Zeile; writerows(rows) schreibt eine ganze Iterable auf einmal. Beide setzen Felder automatisch in Anführungszeichen, wenn sie Kommas, Anführungszeichen oder Zeilenumbrüche enthalten — dafür musst du nichts tun.

Dicts mit DictWriter schreiben

Wenn deine Daten schon in Dict-Form sind, spart DictWriter den „in Listen umwandeln“-Schritt:

import csv

people = [
    {"name": "Rosa", "age": 30, "city": "Lisbon"},
    {"name": "Ada", "age": 36, "city": "London"},
]

with open("out.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
    writer.writeheader()
    writer.writerows(people)

Das fieldnames-Argument steuert sowohl den Header als auch die Spaltenreihenfolge. Schlüssel in deinen Dicts, die nicht in fieldnames stehen, werden stillschweigend verworfen (oder du wirfst mit extrasaction="raise").

Verschiedene Trennzeichen und Quoting

Nicht jede „CSV“ nutzt Kommas. Europäische Locales nutzen oft ;, tab-getrennte Dateien \t, manche Systeme |. Übergib ein delimiter=-Argument:

import csv

with open("data.tsv", newline="") as f:
    reader = csv.reader(f, delimiter="\t")
    for row in reader:
        print(row)

Für Dateien mit ungewöhnlichen Quoting-Regeln erlaubt csv.register_dialect(...) eine einmalige Konfiguration zur Wiederverwendung. Für die meisten Dateien reichen die Defaults plus delimiter=.

Encoding

CSV-Dateien sind Text — sie haben Encodings. UTF-8 ist der moderne Default; aus Excel stammende Dateien unter Windows nutzen manchmal cp1252 oder enthalten ein UTF-8-BOM. Sei explizit:

with open("data.csv", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    ...

Siehst du UnicodeDecodeError, hat die Datei nicht das geratene Encoding. Versuch utf-8-sig (behandelt das Excel-BOM), cp1252 oder latin-1 als übliche Verdächtige.

CSV-Zeilen in nützliche Typen verwandeln

Da jeder Wert als String kommt, bleibt das Parsen dir überlassen:

main.py
Output
Click Run to see the output here.

(StringIO lässt uns das Beispiel ohne echte Datei ausführen — in echtem Code würdest du open(path) nutzen.)

Für CSVs mit kniffligen Typen (Daten, nullable Zahlen, true/false in zehn Schreibweisen) denk an pandas — es hat für die meisten Konventionen eingebaute Regeln.

Wann du zu pandas greifst

pandas.read_csv(path) liefert ein DataFrame, die richtige Struktur in dem Moment, in dem du:

  • Zeilen filtern willst: df[df["active"] == True]
  • Aggregieren willst: df.groupby("city")["age"].mean()
  • Mit einer anderen Tabelle joinen willst
  • Mit einfachem Format zurückschreiben willst
import pandas as pd

df = pd.read_csv("people.csv")
adults = df[df["age"] >= 18]
adults.to_csv("adults.csv", index=False)

Für kleine, lineare Lesevorgänge ist pandas übertrieben — und es ist eine schwere Abhängigkeit (in einer virtuellen Umgebung installieren). Aber für alles Datenförmige ist es das Werkzeug, zu dem die meisten Python-Analystinnen greifen.

Sehr große Dateien streamen

csv.reader ist bereits lazy — er liest Zeile für Zeile. Halte es so, indem du iterierst (nicht list(reader) im Voraus aufrufst), und dein Speicherbedarf bleibt flach, egal wie groß die Datei ist:

import csv

with open("huge.csv", newline="") as f:
    reader = csv.DictReader(f)
    error_count = 0
    for row in reader:
        if row["status"] == "error":
            error_count += 1

print(f"Found {error_count} errors.")

Das verarbeitet eine 10-GB-Datei genauso zufrieden wie eine 10-KB-Datei, solange du die Zeilen nicht in einer Liste ansammelst.

Ein paar Gewohnheiten

  • Übergib beim Lesen und Schreiben von CSVs immer newline="" an open.
  • Nutz DictReader/DictWriter, wenn die Datei Header hat — lesbarer als Integer-Indizes.
  • Sei beim Encoding explizit, besonders bei Dateien aus Excel oder nicht-englischen Quellen.
  • Wandle Typen direkt beim Lesen um, damit nachgelagerter Code nichts nachholen muss.
  • Greif zu pandas, sobald du Daten analysieren willst, nicht nur verschieben.

Als Nächstes

Du kannst jetzt JSON und CSV lesen. Die letzte reale Fertigkeit, die wir behandeln, ist Daten über das Netz holen — das ist das nächste Dokument, über HTTP-Anfragen mit der requests-Bibliothek.

Häufig gestellte Fragen

Wie lese ich eine CSV-Datei in Python?

Nutz das eingebaute csv-Modul. csv.reader liefert jede Zeile als Liste von Strings; csv.DictReader nutzt die erste Zeile als Header und liefert jede Zeile als Dict. Öffne die Datei mit newline='', damit Python Zeilenumbrüche nicht verstümmelt: with open('data.csv', newline='') as f:.

Wie schreibe ich eine CSV-Datei in Python?

Kombinier csv.writer mit einer im Schreibmodus geöffneten Datei und newline=''. Ruf writer.writerow([...]) pro Zeile oder writer.writerows([[...], [...]]) für einen Batch. Für dict-basierte Daten: csv.DictWriter — er kümmert sich automatisch um die Header.

Soll ich das csv-Modul oder pandas nutzen?

Nimm csv für schnelle Lese- und Schreibvorgänge, zeilenweise verarbeitete Dateien und wenn du keine zusätzliche Abhängigkeit willst. Nimm pandas, wenn du filtern, gruppieren oder joinen willst — oder wenn die Datei groß genug ist, dass vektorisierte Operationen zählen. Beide verarbeiten dieselben Dateien; die Wahl hängt davon ab, was du nach dem Laden tust.

Warum hat meine CSV unter Windows Leerzeilen zwischen den Zeilen?

Du hast die Datei ohne newline='' geöffnet. Das csv-Modul schreibt eigene Zeilenendungen; ohne dieses Argument fügt Python unter Windows zusätzliche ein. Öffne CSV-Dateien immer mit open(path, newline='') — beim Lesen und Schreiben.

Lerne mit Coddy zu programmieren

LOS GEHT'S