VM-LEARNING /class.xii ·track.cs ·ch-1-7 session: 2026_27
$cd ..

~/CSV Files

root@vm-learning ~ $ open ch-1-7
UNIT 1 ▪ CHAPTER 7
07
CSV Files
csv module · writer · writerow · writerows · reader · DictReader · Worked Programs
A CSV file (Comma-Separated Values) is a plain text file that stores tabular data — rows and columns — with a comma (or another separator) between the columns. It is the universal translator between Python, Excel, Google Sheets, and almost every database in the world.
Real-life analogy. Think of CSV as spreadsheet paper in plain English. If Excel and Python want to exchange data, they both speak CSV. No fancy format, no hidden bytes — just lines where commas mark the column borders.

7.1 What is a CSV file?

Each line is one record (one row). Inside a line, fields (columns) are separated by a comma. Here is marks.csv as it sits on disk — open it in Notepad and you’ll see exactly this:

roll,name,marks 1,Asha,92 2,Rahul,78 3,Riya,85 4,Ankit,71

The first line is an optional header — it names the columns. The rest are data rows. Open the same file in Excel / LibreOffice and it appears as a proper table.

7.2 Why do we use CSV?

7.2.1 CSV vs Text vs Binary — at a glance

Text (.txt)CSV (.csv)Binary (.dat)
StructureFree-form linesRows & columnsRaw bytes
Opens in Excel?No (plain view)Yes (as a table)No
Keeps Python types?No — always strNo — always strYes (with pickle)
Ideal forLogs, notesSpreadsheet exchangeImages, Python objects

7.3 The csv Module

Python ships with a built-in module called csv that reads and writes CSV correctly — handling edge cases like commas inside a quoted field, newlines inside a field, and different separators.

import csv

7.3.1 Why not just use split(",")?

For the simple files in your CBSE practicals you technically could. But consider a single row like:

4,"Ankit Kumar, Jr.",71

"Ankit Kumar, Jr." has a comma inside quotes — it is still one field. Calling .split(",") would wrongly break it into four pieces. The csv module understands quoting, so always prefer it.

7.4 Writing a CSV File

7.4.1 Step 1 — open the file and create a writer

import csv with open("marks.csv", "w", newline="") as f: # note: newline="" w = csv.writer(f) w.writerow(["roll", "name", "marks"]) # header w.writerow([1, "Asha", 92]) w.writerow([2, "Rahul", 78]) w.writerow([3, "Riya", 85])
Always pass newline="" when opening a CSV file (both for reading and writing). On Windows, without it, Python writes extra \r characters — producing blank lines between every row when Excel opens the file.

7.4.2 writer.writerow(row_list) — write one row

Takes a list (or tuple) of values and writes them as one comma-separated line, adding the newline for you.

7.4.3 writer.writerows(list_of_rows) — write many rows

import csv rows = [ ["roll", "name", "marks"], [1, "Asha", 92], [2, "Rahul", 78], [3, "Riya", 85], [4, "Ankit", 71], ] with open("marks.csv", "w", newline="") as f: csv.writer(f).writerows(rows) # one call writes every row
writerow = one row at a time. writerows = everything in one shot (takes a list of rows). Do not mix them up — writerows with a single row writes each character as a separate column.

7.4.4 Appending rows — mode "a"

import csv new_rows = [ [5, "Karan", 66], [6, "Meera", 95], ] with open("marks.csv", "a", newline="") as f: csv.writer(f).writerows(new_rows) # appended at the end

7.5 Reading a CSV File

7.5.1 csv.reader — iterate over rows

import csv with open("marks.csv", "r", newline="") as f: r = csv.reader(f) for row in r: print(row)
['roll', 'name', 'marks'] ['1', 'Asha', '92'] ['2', 'Rahul', '78'] ['3', 'Riya', '85'] ['4', 'Ankit', '71']
Every value read from a CSV is a string — even numbers. Convert with int() / float() before doing math.

7.5.2 Skipping the header row

import csv with open("marks.csv", "r", newline="") as f: r = csv.reader(f) header = next(r) # read the first line into 'header' for row in r: # remaining rows print(row[1], "scored", row[2])

7.5.3 Converting columns as you read

import csv total = 0 count = 0 with open("marks.csv", "r", newline="") as f: r = csv.reader(f) next(r) # skip header for roll, name, marks in r: # unpacking total += int(marks) # string → int count += 1 print(f"Average marks = {total/count:.2f}")

7.6 Custom Delimiters — TSV, semicolons, pipes

CSV’s “C” stands for comma, but the separator is configurable. European spreadsheets often use ; because they write decimals with a comma; log files sometimes use TAB (\t) or |.

import csv # write using ';' as separator with open("marks_eu.csv", "w", newline="") as f: w = csv.writer(f, delimiter=";") w.writerow(["roll", "name", "marks"]) w.writerow([1, "Asha", 92]) # read it back — tell the reader to expect the same delimiter with open("marks_eu.csv", "r", newline="") as f: for row in csv.reader(f, delimiter=";"): print(row)

7.6.1 Other useful csv options

OptionWhat it does
delimiterColumn separator (default ",")
quotecharCharacter that wraps text fields (default '"')
quotingWhen to quote — csv.QUOTE_ALL, QUOTE_MINIMAL, …
lineterminatorString written at the end of each row

7.7 DictReader & DictWriter — readable, self-documenting code

Instead of accessing columns by index (row[0], row[1] …) — which is easy to confuse — you can access them by column name.

7.7.1 csv.DictReader

import csv with open("marks.csv", "r", newline="") as f: r = csv.DictReader(f) # uses first row as keys for row in r: print(row["name"], "->", row["marks"])

7.7.2 csv.DictWriter

import csv rows = [ {"roll": 1, "name": "Asha", "marks": 92}, {"roll": 2, "name": "Rahul", "marks": 78}, ] with open("marks.csv", "w", newline="") as f: w = csv.DictWriter(f, fieldnames=["roll", "name", "marks"]) w.writeheader() # writes the header row w.writerows(rows) # every dict becomes one row
Use DictReader / DictWriter whenever the file has a header row — your code becomes self-documenting, and adding / reordering columns later does not break it.

7.8 CBSE-style Worked Programs

7.8.1 Create a CSV of student records

import csv rows = [] while True: roll = int(input("Roll : ")) name = input("Name : ") marks = int(input("Marks: ")) rows.append([roll, name, marks]) if input("Another? (y/n): ").lower() != "y": break with open("students.csv", "w", newline="") as f: w = csv.writer(f) w.writerow(["roll", "name", "marks"]) w.writerows(rows) print("File written.")

7.8.2 Display every record in the CSV

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

7.8.3 Count records where marks > 75

import csv count = 0 with open("students.csv", "r", newline="") as f: r = csv.reader(f) next(r) # skip header for row in r: if int(row[2]) > 75: count += 1 print("High scorers:", count)

7.8.4 Search a student by roll number

import csv target = input("Roll to find: ") with open("students.csv", "r", newline="") as f: r = csv.reader(f) next(r) for row in r: if row[0] == target: print("Found:", row) break else: print("No match.")

7.8.5 Append a new student interactively

import csv rec = [ int(input("Roll : ")), input("Name : "), int(input("Marks: ")), ] with open("students.csv", "a", newline="") as f: csv.writer(f).writerow(rec) print("Appended.")

7.8.6 Update marks for a given roll number

Like binary files, CSV updates follow the read-all → modify → write-all pattern.

import csv target = "2" new_marks = "88" # 1) read with open("students.csv", "r", newline="") as f: rows = list(csv.reader(f)) # 2) modify (skip header) for row in rows[1:]: if row[0] == target: row[2] = new_marks # 3) write back with open("students.csv", "w", newline="") as f: csv.writer(f).writerows(rows) print("Updated.")

7.8.7 Copy passing students (marks ≥ 33) to another CSV

import csv with open("students.csv", "r", newline="") as src, \ open("passed.csv", "w", newline="") as dst: r = csv.reader(src) w = csv.writer(dst) header = next(r) w.writerow(header) for row in r: if int(row[2]) >= 33: w.writerow(row) print("Copied passing students.")

7.8.8 Class topper from the CSV

import csv with open("students.csv", "r", newline="") as f: r = csv.DictReader(f) topper = max(r, key=lambda row: int(row["marks"])) print("Topper:", topper["name"], "—", topper["marks"])

7.8.9 Merge two CSVs into one

import csv with open("all.csv", "w", newline="") as out: w = csv.writer(out) for fname in ("section_A.csv", "section_B.csv"): with open(fname, "r", newline="") as f: w.writerows(csv.reader(f)) print("Merged.")

7.8.10 CSV → text summary report

import csv with open("students.csv", "r", newline="") as src, \ open("report.txt", "w") as dst: r = csv.DictReader(src) for row in r: line = f"{row['roll']:>3}. {row['name']:<15} {row['marks']}\n" dst.write(line) print("Report saved.")

7.9 Common Mistakes to Avoid

#MistakeFix
1Missing newline="" while openingAlways pass it — blank lines vanish
2Forgetting that every value read is a stringConvert with int() / float() before math
3writerows(single_row) — each character becomes a columnUse writerow for one row
4Forgetting next(r) — header is treated as dataCall next(r) once to skip it
5Using split(",") on rows with quoted commasUse the csv module
6Writing in mode "w" when you meant "a""w" wipes; "a" appends
7Wrong delimiter (file uses ;)Pass delimiter=";" to reader / writer
8Trying to update a row in the middle of the fileUse the read-all / modify / write-all pattern

Quick-revision summary

  • A CSV is a plain-text, comma-separated table — the universal format between Python, Excel and databases.
  • import csv; open the file with newline="" — always.
  • csv.writer(f).writerow(row) writes one row; writerows(list_of_rows) writes many at once.
  • csv.reader(f) yields each row as a list of strings; convert numeric columns before math.
  • Skip the header with next(reader).
  • DictReader / DictWriter let you access columns by name — recommended when the file has a header.
  • Custom separators: pass delimiter=";" (or any other character).
  • Updating rows follows the read-all → modify → write-all pattern, just like binary files.
🧠Practice Quiz — test yourself on this chapter