Cohort 4Register

PART 2 · PYTHON FOUNDATIONS · CHAPTER 5

Loops, comprehensions and unpacking

FreeLesson 28 of 78

A comprehension is a loop that builds a collection in one expression. Use it when it reads like a sentence, and a plain loop when it does not.

LIST, SET AND DICT COMPREHENSIONSPYTHON 3.12
import csv
rows = list(csv.DictReader(open("orders.csv")))

amounts = [float(r["amount"]) for r in rows
           if r["status"] == "delivered"]
print(len(amounts), max(amounts))

statuses = {r["status"] for r in rows}            # set
by_id = {int(r["order_id"]): r["status"] for r in rows}
print(sorted(statuses), by_id[104])

matrix = [[1, 2], [3, 4], [5]]
print([x for row in matrix for x in row])        # flatten

Output

12 3498.0
['cancelled', 'delivered', 'returned'] cancelled
[1, 2, 3, 4, 5]
ZIP, ENUMERATE, UNPACKING, ANY, ALLPYTHON 3.12
ids = [101, 102, 103]
names = ["Aarav", "Diya"]
print(list(zip(ids, names)))            # stops at shortest

for i, name in enumerate(names, start=1):
    print(i, name)

first, *rest = [101, 102, 103, 104]
print(first, rest)

print(any(n.startswith("D") for n in names),
      all(i > 100 for i in ids))

if (n := len(ids)) > 2:                 # walrus: assign + test
    print("big batch of", n)

Output

[(101, 'Aarav'), (102, 'Diya')]
1 Aarav
2 Diya
101 [102, 103, 104]
True True
big batch of 3
FOR ... ELSEPYTHON 3.12
targets = [1499, 9999]
amounts = [1198, 796, 1499]
for t in targets:
    for a in amounts:
        if a == t:
            print(t, "found")
            break
    else:                       # runs only if no break
        print(t, "not found")

Output

1499 found
9999 not found

The else of a loop runs when the loop finishes without break. Handy for "search and report if missing", and a common "what does this print?" question.

MAP/FILTER VS COMPREHENSIONS VS GENERATORSPYTHON 3.12
amounts = ["1198.00", "796.00", "", "1499.00"]

total_a = sum(map(float, filter(None, amounts)))
total_b = sum(float(a) for a in amounts if a)   # same, clearer
print(total_a, total_b)

squares = [x * x for x in range(1_000)]          # builds a list
total_c = sum(x * x for x in range(1_000))       # no list
print(len(squares), total_c)

Output

3493.0 3493.0
1000 332833500

Practice before you move on

  1. Rewrite one loop from this lesson as a comprehension and check that the output is the same.
  2. Use enumerate and zip to print every order_id of orders.csv with its row number, starting at 1.