Use the built-in CSV module when you need rows without another dependency. Use pandas when you need column math, filtering, or grouping. The examples keep the answer copyable, then deal with headers, writing, encodings, and the Excel quirks that cause real failures.
🎙️ Published & recorded: ·
DictReader uses the first row as column names, so each later row is a dictionary. Open the file with newline set to an empty string because the CSV module needs to control newlines itself. State UTF-8 rather than trusting the operating system default. Every value still arrives as text, so convert amounts before doing arithmetic.
import csv
with open("users.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
print(row["name"], row["email"])
total += float(row["amount"])
# row = {"name": "Ada", "email": "[email protected]", ...}
Prefer named fields over row zero and row two. The code survives a reordered file, and a missing header produces a useful KeyError instead of silently reading the wrong column.
Plain csv reader returns lists. Call next once only when the file really has a header you want to skip. For analysis, pandas reads a whole table and infers column types. Set the separator explicitly for semicolon exports, and use selected columns when a wide file wastes memory.
with open("data.csv", newline="", encoding="utf-8") as f:
reader = csv.reader(f)
next(reader) # skip header, if present
for row in reader:
print(row[0], row[2])
import pandas as pd
df = pd.read_csv("users.csv")
df.head() # first 5 rows
df["amount"].sum() # typed column math
pd.read_csv("f.csv", sep=";")
pd.read_csv("f.csv", skiprows=2)
pd.read_csv("f.csv", usecols=["name", "amount"])
Choose plainly: if rows feed your program, the standard library is enough. If you are grouping, joining, filtering, or calculating across columns, pandas earns its installation cost.
DictWriter needs the output column order up front. Write the header once, then write the dictionaries. Keep newline empty on Windows too; leaving it out is the usual cause of a blank line appearing between every record.
rows = [{"name": "Ada", "score": 95}, {"name": "Lin", "score": 88}]
with open("out.csv", "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=["name", "score"])
w.writeheader()
w.writerows(rows)
Do not build rows by joining values with commas. A name such as Smith, John needs quoting and escaping, and the writer handles that correctly.
A common Windows failure is UnicodeDecodeError: charm ap codec can't decode byte zero x nine d. It means Python used the Windows default encoding for a file that is probably UTF-8. Add encoding equals UTF-8 to open. If an Excel export leaves an invisible marker before the first heading, use UTF-8 sig instead.
UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d
# fix:
open("users.csv", newline="", encoding="utf-8")
KeyError: 'name'
# if print(reader.fieldnames) shows '\ufeffname', remove the Excel BOM:
open("users.csv", newline="", encoding="utf-8-sig")
reader.fieldnames first. If the first name starts with \ufeff, switch to utf-8-sig. If every row appears as one giant field, inspect the file and set delimiter=";" or pandas sep=";". If output has blank lines on Windows, add newline="".Never repair a real CSV with line split comma. The value Smith, John is legal when quoted, and manual splitting silently turns it into two columns. Use the parser and fix its encoding or delimiter rather than replacing it.