Repetition builds fluency. This chapter is a set of short, self-contained programs that exercise lists, tuples, and dictionaries. For each one, read the goal, try to solve it yourself first, then compare with the solution and the idea behind it. Each snippet is intentionally small so you can run it in seconds.
The formula converts a Celsius reading into its Fahrenheit equivalent by multiplying by 9/5 and adding 32.
celsius = 25.0
fahrenheit = celsius * 9 / 5 + 32
print(fahrenheit) # 77.0
Multiply length by width. Notice how a small reusable function makes the same math callable many times.
def rect_area(length, width):
return length * width
print(rect_area(5, 4)) # 20
Distance equals speed multiplied by time. Keep the units consistent: kilometres per hour times hours.
speed_kmh = 60
time_h = 2.5
distance_km = speed_kmh * time_h
print(distance_km) # 150.0
If a lift carries a maximum load per trip, the number of trips equals the total load divided by the capacity, rounded up to the next whole trip. The math.ceil helper handles the rounding.
import math
total_weight = 950
capacity = 300
trips = math.ceil(total_weight / capacity)
print(trips) # 4
Given two points, the slope is the rise over the run, and the intercept is found by plugging one point into y = mx + b.
def line_from_points(p1, p2):
x1, y1 = p1
x2, y2 = p2
m = (y2 - y1) / (x2 - x1)
b = y1 - m * x1
return m, b
m, b = line_from_points((1, 2), (3, 6))
print(m, b) # 2.0 0.0
y = 2.0x + 0.0. Two distinct points always define a unique straight line, which is why this same idea reappears in linear regression later in the book.
Add every number in a list. The built-in sum is the idiomatic choice.
nums = [4, 8, 15, 16]
print(sum(nums)) # 43
Track a running maximum, or use the built-in max.
nums = [3, 9, 2, 11, 5]
largest = nums[0]
for n in nums[1:]:
if n > largest:
largest = n
print(largest) # 11
A set keeps only unique values; converting back to a list drops the repeats while preserving a set of distinct items.
data = [1, 2, 2, 3, 3, 3]
unique = list(set(data))
print(unique) # order may vary
If the set has the same length as the list, nothing was duplicated.
def all_unique(items):
return len(items) == len(set(items))
print(all_unique([1, 2, 3])) # True
print(all_unique([1, 2, 2])) # False
Slice notation with a step of -1 produces a reversed copy without modifying the original.
nums = [1, 2, 3, 4]
print(nums[::-1]) # [4, 3, 2, 1]
A single pass can tally both categories using the modulo operator.
nums = [1, 2, 3, 4, 5, 6]
even = sum(1 for n in nums if n % 2 == 0)
odd = len(nums) - even
print(even, odd) # 3 3
Set comparison answers this directly: every element of the first set is also in the second.
a = {2, 3}
b = {1, 2, 3, 4}
print(a.issubset(b)) # True
Slide along the list comparing each neighbour pair and keep the largest gap. zip pairs adjacent items neatly.
nums = [1, 7, 3, 12]
gaps = [abs(x - y) for x, y in zip(nums, nums[1:])]
print(max(gaps)) # 9
Concatenate and sort is simple; walking both lists with two pointers is the classic efficient merge.
def merge(a, b):
out = []
i = j = 0
while i < len(a) and j < len(b):
if a[i] <= b[j]:
out.append(a[i]); i += 1
else:
out.append(b[j]); j += 1
out.extend(a[i:])
out.extend(b[j:])
return out
print(merge([1, 3, 5], [2, 4, 6])) # [1, 2, 3, 4, 5, 6]
Rotation shifts elements so the front moves to the back. Slice the list into two pieces and rejoin them in the new order.
def rotate(items, k):
k = k % len(items)
return items[k:] + items[:k]
print(rotate([1, 2, 3, 4, 5], 2)) # [3, 4, 5, 1, 2]
k % len(items) guard handles that edge case before slicing.
Pair each key with its matching value using zip.
keys = ["name", "age"]
values = ["Mira", 24]
merged = dict(zip(keys, values))
print(merged) # {'name': 'Mira', 'age': 24}
Use update in a loop, or chain the modern union operator that joins them left to right.
a = {"x": 1}
b = {"y": 2}
c = {"z": 3}
combined = {}
for d in (a, b, c):
combined.update(d)
print(combined) # {'x': 1, 'y': 2, 'z': 3}
When keys repeat, decide how to combine values. Here duplicate keys have their values added instead of overwritten.
a = {"apples": 3, "mangoes": 2}
b = {"apples": 4, "grapes": 5}
total = {}
for d in (a, b):
for key, val in d.items():
total[key] = total.get(key, 0) + val
print(total) # {'apples': 7, 'mangoes': 2, 'grapes': 5}
Split the text into words and count how often each appears. collections.Counter does the whole tally in one line.
from collections import Counter
sentence = "the cat and the dog"
counts = Counter(sentence.split())
print(counts) # Counter({'the': 2, 'cat': 1, 'and': 1, 'dog': 1})
A tuple is palindromic if it reads the same forwards and backwards, which a reversed comparison detects directly.
def is_palindrome_tuple(t):
return t == t[::-1]
print(is_palindrome_tuple((1, 2, 1))) # True
print(is_palindrome_tuple((1, 2, 3))) # False
For simple key conflicts, the union operator keeps the value from the right-hand dictionary, which is useful when later data should win.
a = {"name": "Leo", "score": 70}
b = {"score": 85, "city": "Pune"}
combined = a | b
print(combined) # {'name': 'Leo', 'score': 85, 'city': 'Pune'}
sum with an explicit loop, or swap a loop for a list comprehension). Confirm every version produces the same output. Then write one new program of your own that combines at least three of the ideas, such as finding the most frequent word in a paragraph after removing duplicates.