Board Formulas
🐍 PythonπŸ“… Day 18

Binary and CSV Files in Python

Save Python objects to binary files with pickle, search and update records, and read and write spreadsheet-style CSV files with the csv module.

🎯

Learning objectives

  • β†’Explain how binary and CSV files differ from plain text files
  • β†’Store and load Python objects with pickle.dump() and pickle.load()
  • β†’Append, search and update records in a binary file
  • β†’Write and read CSV files with csv.writer and csv.reader, using newline=''

πŸ’‘ Key points

  • Binary files store bytes, not readable text. Open them with a b mode: 'wb', 'rb', 'ab', 'rb+'.
  • pickle.dump(obj, f) saves almost any Python object (list, dict, tuple...) to a binary file; pickle.load(f) reads one object back.
  • Each load() call reads one object. At the end of the file it raises EOFError, so read in a loop inside try/except EOFError.
  • A CSV (comma-separated values) file is plain text: one record per line, fields separated by commas. Spreadsheet programs open it directly.
  • csv.writer(f) gives writerow() for one row and writerows() for many; csv.reader(f) returns each row as a list of strings.
  • Open CSV files with newline='' so the csv module controls line endings (otherwise blank rows can appear on Windows).
  • Only unpickle files you trust: loading a pickle can run code hidden inside it.

πŸ’» Code examples(6)

#1Saving and loading one object with pickle
python
import pickle

student = {"roll": 1, "name": "Amit", "marks": 87}
with open("student.dat", "wb") as f:
    pickle.dump(student, f)

with open("student.dat", "rb") as f:
    data = pickle.load(f)
print(data)
print(data["name"], type(data))
Output
{'roll': 1, 'name': 'Amit', 'marks': 87}
Amit <class 'dict'>
The dict comes back as a real dict, ready to use. With a text file you would have to convert everything to strings and back yourself.
#2Many records: dump in a loop, load until EOFError
python
import pickle

records = [[1, "Amit", 87], [2, "Priya", 92],
           [3, "Ravi", 76]]
with open("students.dat", "wb") as f:
    for rec in records:
        pickle.dump(rec, f)

with open("students.dat", "rb") as f:
    while True:
        try:
            rec = pickle.load(f)
            print(rec)
        except EOFError:
            break
Output
[1, 'Amit', 87]
[2, 'Priya', 92]
[3, 'Ravi', 76]
Each dump() writes one record. Reading stops cleanly when load() raises EOFError (end of file).
#3Appending and searching
python
import pickle

with open("students.dat", "ab") as f:
    pickle.dump([4, "Neha", 95], f)

def search(roll):
    with open("students.dat", "rb") as f:
        try:
            while True:
                rec = pickle.load(f)
                if rec[0] == roll:
                    return rec
        except EOFError:
            return None

print(search(4))
print(search(9))
Output
[4, 'Neha', 95]
None
'ab' adds a record without touching the existing ones. The search reads records one by one and stops at the first match.
#4Updating a record
python
import pickle

recs = []
with open("students.dat", "rb") as f:
    try:
        while True:
            recs.append(pickle.load(f))
    except EOFError:
        pass

for rec in recs:
    if rec[1] == "Ravi":
        rec[2] = 81            # corrected marks

with open("students.dat", "wb") as f:
    for rec in recs:
        pickle.dump(rec, f)
print(recs)
Output
[[1, 'Amit', 87], [2, 'Priya', 92], [3, 'Ravi', 81], [4, 'Neha', 95]]
The simplest safe update: read every record into a list, change the one you need, then write them all back with 'wb'.
#5Writing a CSV file
python
import csv

rows = [["Amit", 87, "A"], ["Priya", 92, "A+"],
        ["Ravi", 76, "B"]]
with open("marks.csv", "w", newline="") as f:
    w = csv.writer(f)
    w.writerow(["Name", "Marks", "Grade"])
    w.writerows(rows)

with open("marks.csv") as f:   # view the raw text
    print(f.read(), end="")
Output
Name,Marks,Grade
Amit,87,A
Priya,92,A+
Ravi,76,B
writerow() writes the header and writerows() writes all the data rows at once. Numbers are converted to text automatically.
#6Reading a CSV file
python
import csv

with open("marks.csv", newline="") as f:
    r = csv.reader(f)
    header = next(r)            # first row
    count = total = 0
    for row in r:
        print(row)
        total += int(row[1])    # text β†’ number
        count += 1
print("Columns:", header)
print("Average:", round(total / count, 2))
Output
['Amit', '87', 'A']
['Priya', '92', 'A+']
['Ravi', '76', 'B']
Columns: ['Name', 'Marks', 'Grade']
Average: 85.0
Every field comes back as a string ('87', not 87), so convert before doing maths. next(r) reads the header row so the loop sees only data.

🎯 Practice

Q1. Which mode opens a binary file to add records at the end?+

'ab'

Q2. What exception does pickle.load() raise when there are no more objects to read?+

EOFError

Q3. Why do we pass newline='' when opening a CSV file?+

The csv module writes its own line endings. newline='' stops Python from translating them again, which would otherwise create blank rows on Windows.

Q4. Using marks.csv from the examples, print the names of students who scored more than 80.+

import csv with open('marks.csv', newline='') as f: r = csv.reader(f) next(r) for row in r: if int(row[1]) > 80: print(row[0]) # Amit # Priya

Q5. What is the difference between writerow() and writerows()?+

writerow() writes a single row (one list). writerows() writes many rows at once (a list of lists).

πŸ“ Notes

Text, binary or CSV?

  • Text file (.txt): readable characters. Good for notes, logs and stories. Everything is a string.
  • Binary file (.dat with pickle): stores Python objects exactly as they are β€” lists stay lists, numbers stay numbers. Not readable in Notepad.
  • CSV file (.csv): plain text in rows and columns. Easy to open in a spreadsheet and to share with other programs.

pickle in one picture

Python object --pickle.dump()--> bytes in a file
bytes in a file --pickle.load()--> same Python object

Turning an object into bytes is called pickling (serialisation); turning it back is unpickling.

Other delimiters

Not every "CSV" uses commas. Pass a different delimiter to both the writer and the reader:

w = csv.writer(f, delimiter="|")
r = csv.reader(f, delimiter="|")

If a field itself contains a comma, such as "Delhi, India", the csv module wraps it in quotes automatically, so the file still reads back correctly.

Common mistakes

  • Text mode for pickle: open("a.dat", "w") then pickle.dump() raises TypeError: write() argument must be str, not bytes. Use "wb".
  • "wb" instead of "ab": opening with "wb" erases every record already in the file.
  • Calling load() once: it returns only the first object. Loop until EOFError.
  • Forgetting newline='': extra blank lines between rows when the file is opened on Windows.
  • Doing maths on CSV strings: row[1] + 5 fails; use int(row[1]) + 5.

Next: Day 19 β€” Stack Using a List, your first data structure.