Skip to content

ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ

CSV files

4 min read

Price lists, exam results, Telebirr statements: most tables you'll meet as files are CSV. By the end of this lesson you'll read one into dicts, total a column even when a row is wrong, write a table of your own, and know why a CSV value is never a number until you make it one.

A table as text

A file is a table written as plain text: one per line, with commas between the values. The first row is usually the , naming the columns. Open Files under this runner to see prices.csv, a short Merkato price list:

import csv

with open("prices.csv", newline="", encoding="utf-8") as f:
    rows = list(csv.reader(f))
print(rows)

In the editor, press Escape then Tab to move on.

ፋይሎች1 starting file

prices.csv

item,price
ቡና,320
በርበሬ,180
ምስር,95

csv.reader turns each line into a list of strings, header included. Open CSV files with newline="", as the csv documentation asks: the module handles line endings itself. Without it, a quoted value with a line break inside reads wrong, and on Windows every row you write gets an extra blank line after it.

Lists make you remember that the price is position 1. csv.DictReader uses the header instead: each row becomes a dict whose keys are the column names. Predict the last line:

ውጤቱን ገምቱ

Decide before you look. Guessing wrong is how this sticks.

import csv

with open("prices.csv", newline="", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))
print(rows[0])
print(type(rows[0]["price"]))

Also in the folder with main.py:

prices.csv

item,price
ቡና,320
በርበሬ,180
ምስር,95
Pick the output

Python prints

{'item': 'ቡና', 'price': '320'}
<class 'str'>

A CSV file is text, and the csv module doesn't guess types: every value comes back as a string, even one that looks like a number.

If you picked int, you trusted the way 320 looks. A CSV file has no types, only text, so every value comes back as a str. Look for the quotes in '320'.

ጥያቄ

What does csv.DictReader give you for each row?

Totaling a column

Forget that, and adding up the prices fails on the first row:

To add up the prices, convert each one with int() and keep a running total (lesson 3.2). Real files have mistakes, so this one has a price written as 60 birr. Catch the ValueError (lesson 7.2) and skip that row instead of stopping:

import csv

total = 0
with open("prices.csv", newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        try:
            total = total + int(row["price"])
        except ValueError:
            print(f"Skipping {row['item']}: {row['price']!r}")
print("Total:", total)

In the editor, press Escape then Tab to move on.

ፋይሎች1 starting file

prices.csv

item,price
ቡና,320
ሻይ,60 birr
በርበሬ,180

total is the running total; !r in the f-string shows the bad value with repr (lesson 6.1), quotes included. Now replace the four try/except lines with just total = total + int(row["price"]) and run it: the whole program stops at the third row with ValueError: invalid literal for int() with base 10: '60 birr', and you never get a total.

Writing a table

csv.DictWriter writes dicts as rows. You give it the column names, write the header once, then one row per dict:

import csv

basket = [{"item": "ቡና", "price": 320}, {"item": "ምስር", "price": 95}]

with open("basket.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["item", "price"])
    writer.writeheader()
    for row in basket:
        writer.writerow(row)

In the editor, press Escape then Tab to move on.

It prints nothing; look in Files for basket.csv. The numbers became text on the way out. csv.writer does the same for lists: writer.writerow(["ቡና", 320]).

Why not split(',')?

A line of CSV looks easy to cut with split(",") from lesson 6.1. But a value can have a comma inside it, and then CSV puts the value in double quotes. Predict:

ውጤቱን ገምቱ

Decide before you look. Guessing wrong is how this sticks.

line = '"ቡና, ሲዳሞ",320'
print(line.split(","))
Pick the output

Python prints

['"ቡና', ' ሲዳሞ"', '320']

split cuts at every comma; it knows nothing about quotes. The quotes stay in the pieces, and one value becomes two.

split cut the item in two and kept the quotes. The csv module reads the quotes the way they're meant:

import csv

line = '"ቡና, ሲዳሞ",320'
print(list(csv.reader([line]))[0])

In the editor, press Escape then Tab to move on.

csv.reader reads any list of lines, not only a file. When it writes a value with a comma, it adds the quotes for you. So let the csv module read and write CSV, and never build or cut the commas yourself.

መልመጃ

Spending by category

expenses.csv has a week of spending. Print the total for each category, in the order each category first appears. Use the tally plan from lesson 4.4, adding each amount instead of 1.

Output
transport: 180
food: 430
phone: 45

Your code

import csv

totals = {}
# Read expenses.csv and add each amount to its category's total

In the editor, press Escape then Tab to move on.

ፋይሎች1 starting file

expenses.csv

date,amount,category
2026-09-28,120,transport
2026-09-28,250,food
2026-09-29,60,transport
2026-09-30,180,food
2026-09-30,45,phone
መፍትሄውን አሳይ

This is one way to solve it, not the only one. If yours prints the same thing, it works.

import csv

totals = {}
with open("expenses.csv", newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        category = row["category"]
        totals[category] = totals.get(category, 0) + int(row["amount"])

for category, total in totals.items():
    print(f"{category}: {total}")

ዋና ዋና ነጥቦች

  • CSV is a table as text: one row per line, commas between values, usually a header first.
  • Open CSV files with newline="" and encoding="utf-8".
  • csv.reader gives each row as a list; csv.DictReader as a dict keyed by the header.
  • Every value comes back as a string: convert with int(), and catch ValueError for bad rows.
  • Write with csv.DictWriter or csv.writer; never cut or join the commas yourself.