Control Flow
Topic 4 of 8, with 4 concept checks. Conditionals, loops, and Python's loop-else quirk
Make every branch and loop condition explicit
Execution paths
Trace which condition controls each path, what changes on every iteration, and how break, continue, and loop else clauses affect the route through a Python program.
Core lesson 01
break exits the loop. continue skips to the next iteration. pass does nothing — a syntactic placeholder.
These three keywords control loop execution differently. `break` stops the nearest enclosing loop immediately, skipping any remaining iterations. `continue` ends just the current iteration early and moves to the next one. `pass` isn't loop-specific at all — it's a no-op statement used anywhere Python requires a statement syntactically (empty function bodies, stub classes, placeholder branches).
for i in range(5):
if i == 3:
break
print(i) # 0 1 2
for i in range(5):
if i == 3:
continue
print(i) # 0 1 2 4
if True:
pass # placeholder, does nothingWhat to remember
What's the difference between break, continue, and pass?
Common footguns
- `break`/`continue` inside a nested loop only affect the innermost loop — there's no labeled break in Python.
Core lesson 02
The else block runs only if the loop completes without a break — a clean way to express 'search and not found'.
`for...else` (and `while...else`) is one of Python's more obscure but genuinely useful constructs. The `else` block executes when the loop finishes normally, i.e. the iterable was exhausted or the while-condition became false — but is *skipped* if the loop was exited via `break`. This maps naturally onto search loops where `break` means 'found it, stop early'.
def has_factor(n, candidates):
for c in candidates:
if n % c == 0:
print(f"{c} divides {n}")
break
else:
print("no factor found")
has_factor(15, [2, 4, 6]) # no factor found
has_factor(15, [2, 3, 6]) # 3 divides 15What to remember
What does the else clause on a for loop do?
Common footguns
- Assuming `else` runs when the loop 'fails' or is empty — it actually runs by default and is skipped only by break, which is the opposite of what the name suggests to most people.
for item in items:
if item == target:
break
else:
print("not found") # only runs if break never happenedCore lesson 03
result = value_if_true if condition else value_if_false — reads almost like English.
Python deliberately ordered the ternary expression to read left-to-right like prose, unlike C's `condition ? a : b`. It's an expression, not a statement, so it can be used anywhere a value is expected — assignments, function arguments, list comprehensions.
n = 7
label = 'even' if n % 2 == 0 else 'odd'
print(label) # odd
vals = [x if x > 0 else 0 for x in [-2, 3, -1, 5]]
print(vals) # [0, 3, 0, 5]What to remember
How do you write a one-line conditional expression (ternary) in Python?
Common footguns
- Chaining several ternaries on one line for multi-branch logic — technically legal but hurts readability fast; use if/elif/else instead.
Core lesson 04
It simulates a do-while: run the body at least once, then decide whether to exit — useful when the exit check needs data from inside the loop.
Some languages have a do-while loop that guarantees at least one execution before checking the condition. Python doesn't, so `while True:` combined with a conditional `break` is the idiomatic substitute — common for input-validation loops where you don't know if input is valid until after you've read it.
while True:
raw = input("Enter a positive number: ") if False else "7" # simulated input
if raw.isdigit() and int(raw) > 0:
n = int(raw)
break
print("invalid, try again")
print("got", n)What to remember
Why might you use while True: with an internal break?
Common footguns
- Forgetting the break entirely, or putting it behind a condition that can never become true — an accidental infinite loop.
Python lab
Browser Python lab
Runtime · idle
Python loads on your first run. Your code stays in this browser.
Best practices
- Avoid deep if/else nesting — prefer early returns or guard clauses.
- Use `for item in iterable` instead of `for i in range(len(iterable))` when the index isn't needed.
- Use enumerate() instead of manually tracking an index counter.
- Keep loop bodies short — extract logic into a function if a loop body grows large.
Apply the concept in Interview practice
FizzBuzzeasyHackerRank · O(n) time
Loop 1..n, checking divisibility by 15, then 3, then 5, printing accordingly, else the number itself.
Open problemClimbing StairseasyLeetCode #70 · O(n) time, O(1) space
Fibonacci in disguise: ways(n) = ways(n-1) + ways(n-2). Build iteratively with two variables.
Open problemSearch Insert PositioneasyLeetCode #35 · O(log n) time
Binary search with low/high pointers; when the loop ends, low is the correct insertion index.
Open problemJump GamemediumLeetCode #55 · O(n) time, O(1) space
Track the farthest index reachable so far while scanning left to right; if the current index ever exceeds that farthest reach, return False.
Open problemMissing NumbereasyLeetCode #268 · O(n) time, O(1) space
XOR all indices 0..n with all array values (every number cancels except the missing one), or use sum(range(n+1)) - sum(nums).
Open problemConcept checks
What's the difference between break, continue, and pass?
Hint
One exits the loop entirely.
One skips to the next iteration; the third does nothing at all.
Answer
break exits the loop. continue skips to the next iteration. pass does nothing — a syntactic placeholder.
These three keywords control loop execution differently. `break` stops the nearest enclosing loop immediately, skipping any remaining iterations. `continue` ends just the current iteration early and moves to the next one. `pass` isn't loop-specific at all — it's a no-op statement used anywhere Python requires a statement syntactically (empty function bodies, stub classes, placeholder branches).
for i in range(5):
if i == 3:
break
print(i) # 0 1 2
for i in range(5):
if i == 3:
continue
print(i) # 0 1 2 4
if True:
pass # placeholder, does nothingWatch out
- `break`/`continue` inside a nested loop only affect the innermost loop — there's no labeled break in Python.
What does the else clause on a for loop do?
Hint
It's not about the loop 'failing'.
It runs when the loop finishes WITHOUT hitting a break.
Answer
The else block runs only if the loop completes without a break — a clean way to express 'search and not found'.
`for...else` (and `while...else`) is one of Python's more obscure but genuinely useful constructs. The `else` block executes when the loop finishes normally, i.e. the iterable was exhausted or the while-condition became false — but is *skipped* if the loop was exited via `break`. This maps naturally onto search loops where `break` means 'found it, stop early'.
def has_factor(n, candidates):
for c in candidates:
if n % c == 0:
print(f"{c} divides {n}")
break
else:
print("no factor found")
has_factor(15, [2, 4, 6]) # no factor found
has_factor(15, [2, 3, 6]) # 3 divides 15for item in items:
if item == target:
break
else:
print("not found") # only runs if break never happenedWatch out
- Assuming `else` runs when the loop 'fails' or is empty — it actually runs by default and is skipped only by break, which is the opposite of what the name suggests to most people.
How do you write a one-line conditional expression (ternary) in Python?
Hint
It's a compact if/else that evaluates to a value.
Format: value_if_true if condition else value_if_false.
Answer
result = value_if_true if condition else value_if_false — reads almost like English.
Python deliberately ordered the ternary expression to read left-to-right like prose, unlike C's `condition ? a : b`. It's an expression, not a statement, so it can be used anywhere a value is expected — assignments, function arguments, list comprehensions.
n = 7
label = 'even' if n % 2 == 0 else 'odd'
print(label) # odd
vals = [x if x > 0 else 0 for x in [-2, 3, -1, 5]]
print(vals) # [0, 3, 0, 5]Watch out
- Chaining several ternaries on one line for multi-branch logic — technically legal but hurts readability fast; use if/elif/else instead.
Why might you use while True: with an internal break?
Hint
Python has no native do-while loop.
Think about loops where the exit condition depends on something computed inside the body.
Answer
It simulates a do-while: run the body at least once, then decide whether to exit — useful when the exit check needs data from inside the loop.
Some languages have a do-while loop that guarantees at least one execution before checking the condition. Python doesn't, so `while True:` combined with a conditional `break` is the idiomatic substitute — common for input-validation loops where you don't know if input is valid until after you've read it.
while True:
raw = input("Enter a positive number: ") if False else "7" # simulated input
if raw.isdigit() and int(raw) > 0:
n = int(raw)
break
print("invalid, try again")
print("got", n)Watch out
- Forgetting the break entirely, or putting it behind a condition that can never become true — an accidental infinite loop.