Lecture 3 of 1418 minInteractiveFree lecture

Control flow: decisions and loops

Programs become useful when they can decide and repeat. Learn if, elif and else, for and while loops, and the patterns — counting, filtering, searching — that cover most real scripts. Then trace a loop line by line.

In this lecture you will

  • Write conditions with comparison and boolean operators
  • Predict which values Python treats as true or false
  • Use for loops with range and enumerate, and while loops when the count is unknown
  • Apply counting, accumulating, filtering and searching patterns

So far our programs run from top to bottom, once. Real programs need to choose — only charge VAT for some customers, only alert when disk usage is high — and to repeat — process every row of a file, retry a failed request. Python’s control-flow statements handle both, with very little syntax.

Decisions: if, elif and else

usage = 91  # percent

if usage >= 90:
    print("Critical: free up disk space now")
elif usage >= 75:
    print("Warning: disk filling up")
else:
    print("Disk usage normal")

Python checks each condition in order and runs the first block whose condition is true, then skips the rest. The indented lines are the block. Python uses indentation — conventionally four spaces — instead of braces, so consistent indentation is not style, it is syntax.

Drag the disk usage and watch which conditions Python actually checks. Then swap the order of the tests to see a bug that hides until the right input arrives:

InteractiveThe first true condition winsDrag the slider, then swap the order
Loading visual…

At 91% both tests are true, but Python stops at the first one. Put the strictest condition first, or make each condition exclude the others, such as 75 <= usage < 90.

Conditions are built from comparisons (==, !=, <, <=, >, >=, in) and combined with and, or and not:

if role == "admin" or (role == "editor" and not account_locked):
    allow_publish()

Truthiness

Any object can be used as a condition. Python treats these as false: False, None, 0, 0.0, empty strings, and empty collections — [], {}, set(), (). Almost everything else is true. That allows concise checks:

if not errors:
    print("All checks passed")

Test your intuition. For each value, guess whether if value: runs its block:

InteractiveTruthy or falsy?Guess, then read why
Loading visual…

The strings " ", "0" and "False" catch out experienced developers. When in doubt, be explicit: if count > 0, if name != "" or if result is not None.

Loops: for and while

A for loop runs its block once for each item of an iterable — a list, a string, a file, a range of numbers:

for server in ["web-1", "web-2", "db-1"]:
    print("Checking", server)

for i in range(3):          # 0, 1, 2
    print("Attempt", i + 1)

for index, name in enumerate(["asha", "ravi"], start=1):
    print(index, name)       # 1 asha, 2 ravi

A while loop repeats as long as a condition stays true. Use it when you don’t know in advance how many iterations you need:

attempts = 0
while not connected() and attempts < 5:
    attempts += 1
    wait_and_retry()

Always make sure something inside a while loop eventually makes the condition false — otherwise the loop never ends.

Trace a loop, step by step

The code below counts how many scores pass a threshold. Step through it and watch the current item, the condition and the variables change. This is exactly how an experienced developer “runs” code in their head.

InteractiveTracing a for loop with an if statementUse Step or Run below
Loading visual…

Four patterns that cover most loops

Counting
Start a counter at 0 and add 1 when a condition holds — as in the trace above.
Accumulating
Start a total (0, an empty list, an empty string) and add each item’s contribution.
Filtering
Build a new list containing only the items that pass a test.
Searching
Stop as soon as you find what you need, with break — no point checking the rest.
# Searching with break
for order in orders:
    if order["id"] == target_id:
        print("Found:", order)
        break
else:
    print("No such order")   # runs only if the loop did not break

The else on a loop is unusual but handy: it runs only when the loop finished without break, which makes “found / not found” logic tidy. continue, by contrast, skips the rest of the current iteration and moves to the next item.

Loops and conditions let you write longer programs — which soon become hard to read. The next lecture introduces functions: the main tool for organizing code into named, reusable pieces.

Key takeaways

  • Indentation defines blocks — the lines that belong to an if, for or while.
  • Empty collections, zero, empty strings and None are falsy; almost everything else is truthy.
  • Use for to loop over items, and while only when you loop until a condition changes.
  • break stops a loop early, continue skips to the next item — both make search and filter loops clearer.

Check your understanding

3 questions · answers explained

Q1What does this print? values = []; print("empty" if not values else "has items")

An empty list is falsy, so not values is True and the expression evaluates to "empty". This is the idiomatic way to test whether a collection has items.

Q2Which loop is the best fit for processing every line in a file?

A for loop over an iterable is the natural choice whenever you process each item of a collection or stream. It’s shorter and can’t accidentally loop forever.

Q3In the loop trace, after the loop finishes, what value does s hold?

A for loop’s variable is an ordinary name in the surrounding scope. After the loop it still refers to the last item it was bound to — 88.