Absolute Path

Python for data cheat sheet

The tools of the course on one page, from a file to a report. Each part names the lesson that teaches it.

Read a text file

Lesson: Read a text file

with open("notes.txt", encoding="utf-8") as file:
    text = file.read()     # all the text
lines = text.splitlines()  # a list of lines

with open("notes.txt", encoding="utf-8") as file:
    for line in file:      # one line at a time
        print(line.strip())

for number, line in enumerate(lines, start=1):
    print(number, line)
  • Python closes the file when the block of with ends.
  • Write encoding="utf-8" each time.
  • strip() removes the spaces and the line end around a text.

Rows from a CSV file

Lesson: Rows from a CSV file

import csv

with open("pets.csv", newline="",
          encoding="utf-8") as file:
    rows = list(csv.reader(file))

header = rows[0]  # ['name', 'age']
data = rows[1:]   # each row is a list of text
position = header.index("age")  # 1
ages = [int(row[position]) for row in data]
  • Do not split the lines at the commas yourself. A value can have a comma in it.
  • Write newline="" in each open call for a CSV file.
  • Each value of a CSV file is text. Convert a number with int("12") or float("3.5").

Rows as dictionaries

Lesson: Rows as dictionaries

import csv

def load_pets(file_name):
    with open(file_name, newline="",
              encoding="utf-8") as file:
        rows = list(csv.DictReader(file))
    for row in rows:
        row["age"] = int(row["age"])
    return rows

pets = load_pets("pets.csv")
print(len(pets))  # 2
print(pets[0])    # {'name': 'Biscuit', 'age': 4}

oldest = pets[0]
for pet in pets:
    if pet["age"] > oldest["age"]:
        oldest = pet
  • DictReader uses the header row for the keys of each row.
  • Convert the numbers one time, after you read the file.
  • Look at the number of rows and at the first row before you use the data.

Filter and pick

Lesson: Filter and pick

# Keep some rows
long_trips = [
    trip for trip in trips if trip["minutes"] > 30
]
# Keep one value of each row
starts = [trip["start"] for trip in trips]
# Each value one time, in order
stations = sorted(set(starts))
Code Result
len(values) the number of items
sum(values) the total of the numbers
min(values) the smallest value
max(values) the largest value
sum(values) / len(values) the average
round(7.4567, 1) 7.5

Sort and rank

Lesson: Sort and rank

sorted([34, 6, 20])                # [6, 20, 34]
sorted([34, 6, 20], reverse=True)  # [34, 20, 6]

# Rows by one value. The largest is first.
longest_first = sorted(
    trips,
    key=lambda trip: trip["minutes"],
    reverse=True,
)
top5 = longest_first[:5]

# The one row with the largest value
longest = max(
    trips, key=lambda trip: trip["minutes"]
)

# By the rider, and then by the minutes
by_rider = sorted(
    trips,
    key=lambda t: (t["rider"], t["minutes"]),
)

A lambda is a function in one line. A minus sign in the key, such as -t["minutes"], puts the largest number first.

Count and group

Lesson: Count and group

from collections import Counter

starts = [trip["start"] for trip in trips]
counts = Counter(starts)
counts["Harbor Gate"]  # the count of one value
counts.most_common(2)  # the 2 largest counts

# A total for each group
minutes = {}
for trip in trips:
    bike = trip["bike"]
    total = minutes.get(bike, 0)
    minutes[bike] = total + trip["minutes"]

# The rows of each group
groups = {}
for trip in trips:
    rider = trip["rider"]
    if rider not in groups:
        groups[rider] = []
    groups[rider].append(trip)

get(key, 0) gives 0 for a key that is not in the dictionary yet.

Numbers that describe data

Lesson: Numbers that describe data

import statistics

times = [10, 12, 14, 20, 600]
statistics.mean(times)    # 131.2
statistics.median(times)  # 14
min(times), max(times)    # (10, 600)
  • One strange value moves the mean. It does not move the median.
  • Look at min and max before you trust a mean.
  • statistics.mean([]) stops with an error. Check the length of the list first.

Clean messy data

Lesson: Clean messy data

Code Result
" Old Mill ".strip() "Old Mill"
"MEMBER".lower() "member"
"old mill".title() "Old Mill"
" old mill ".split() ["old", "mill"]
" ".join(["old", "mill"]) "old mill"
def to_number(text):
    try:
        return int(text)
    except ValueError:
        return None  # the text is not a number

# Keep the first row with each trip_id
seen = set()
unique = []
for row in rows:
    if row["trip_id"] not in seen:
        seen.add(row["trip_id"])
        unique.append(row)

Do not change the source file. Count the rows that you remove, and report the count.

Dates and times

Lesson: Dates and times

from datetime import datetime

start = datetime.fromisoformat("2026-06-01T08:15")
start.year, start.month, start.day  # (2026, 6, 1)
start.hour, start.minute            # (8, 15)
start.weekday()       # 0, which is Monday
start.strftime("%A")  # 'Monday'

end = datetime.fromisoformat("2026-06-01T09:00")
(end - start).total_seconds() / 60  # 45.0

# A date in another form
datetime.strptime("01/06/2026", "%d/%m/%Y")
Code Meaning Example
%A the name of the weekday Monday
%d the day of the month 01
%m the month as a number 06
%B the name of the month June
%Y the year 2026
%H:%M the hour and the minute 08:15

Join two tables

Lesson: Join two tables

# A lookup dictionary: from a name to its zone
zone_of = {
    station["name"]: station["zone"]
    for station in stations
}

# Add the value to each row
for trip in trips:
    start = trip["start"]
    trip["zone"] = zone_of.get(start, "unknown")

# The stations that have no trip
used = set([trip["start"] for trip in trips])
no_trips = [
    station["name"]
    for station in stations
    if station["name"] not in used
]

Check the two sides: the keys of the rows that have no match, and the keys of the second table that no row uses. Keep a row with no match under a clear label, and report it.

JSON data

Lesson: JSON data

JSON Python
an object in braces a dictionary
a list in brackets a list
text in double quotes a string
a number an int or a float
true false True False
null None
import json

with open("station.json", encoding="utf-8") as file:
    station = json.load(file)   # from a file
print(station["hours"]["from"])

point = json.loads('{"x": 2, "y": 5}')  # from text
text = json.dumps(point, indent=2)      # to text

# A file with one JSON value on each line
events = []
with open("events.jsonl", encoding="utf-8") as file:
    for line in file:
        if line.strip() != "":
            events.append(json.loads(line))

Words in text

Lesson: Words in text

from collections import Counter

def words(text):
    result = []
    for piece in text.lower().split():
        word = piece.strip(".,!?;:")
        if word != "":
            result.append(word)
    return result

counts = Counter()
for comment in comments:
    counts.update(words(comment))

# A whole word, and not a piece of a word
"art" in words("The start was hard")  # False

# Chunks of 2 items
for start in range(0, len(items), 2):
    print(items[start:start + 2])

Leave out the stop words, such as the, a and is, before you look at the largest counts.

Write files

Lesson: Write files

Mode Meaning
"r" read. This is the default.
"w" write. Python empties a file that exists.
"a" append. Python adds to the end of the file.
with open("notes.txt", "w",
          encoding="utf-8") as file:
    file.write("First line\n")

with open("pets.csv", "w", newline="",
          encoding="utf-8") as file:
    writer = csv.DictWriter(
        file, fieldnames=["name", "age"]
    )
    writer.writeheader()
    writer.writerows(pets)

print(f"[{'Old Mill':<12}]")  # [Old Mill    ]
print(f"[{42:>6}]")           # [    42]
print(f"[{3.14159:>8.2f}]")   # [    3.14]

In an f-string, <12 puts a value to the left in 12 characters, >6 puts it to the right in 6 characters, and .2f gives 2 digits after the decimal point.