Python Conditionals and Loops
AI-assistedDrafted with AI assistance and reviewed before publishing; examples are version-pinned. Verify against official docs when in doubt.
Programs become useful when they can branch on conditions and repeat work without repetition in the source. This chapter covers both, plus the details that make Python’s version feel different from other languages.
Environment
Examples are verified on Python 3.13:
python --version
# Python 3.13.x
Save a snippet as flow.py and run python flow.py.
if / elif / else
score = 85
if score >= 90:
print("excellent")
elif score >= 60:
print("pass")
else:
print("needs work")
Conditions are evaluated top to bottom and the first true branch wins. Order them from most to least specific: putting score >= 60 first would make the >= 90 branch unreachable.
Python has no switch-style fallthrough and no parentheses requirement. The colon and indentation are the syntax.
What counts as false
You rarely need len(items) > 0. These values are falsy:
for value in [None, False, 0, 0.0, "", [], (), {}, set()]:
print(repr(value), "->", bool(value))
Everything else is truthy, including non-empty strings such as "0" and "False".
Two idioms that are easy to confuse:
if not items: # false for None, [], "", 0
if items is None: # true only for None
Use is None when “missing” must be distinguished from “empty”. Use not x when any empty value should be treated the same.
Conditional expressions and the walrus operator
status = "adult" if age >= 18 else "minor"
Since Python 3.8 you can also bind a name inside a condition:
if (count := len(items)) > 10:
print(f"too many: {count}")
The walrus operator is worth using when the value is needed twice: once for the test, once in the body.
for loops
for iterates over an iterable, not over indices:
for name in ["python", "go", "rust"]:
print(name)
When you need the position, use enumerate instead of range(len(...)):
for index, name in enumerate(["python", "go", "rust"], start=1):
print(index, name)
# 1 python
# 2 go
# 3 rust
range is for counting, not for indexing into a sequence you already have:
for i in range(3): # 0 1 2
print(i)
list(range(1, 10, 2)) # [1, 3, 5, 7, 9]
Iterating two sequences in parallel uses zip, which stops at the shorter one:
for key, value in zip(["a", "b"], [1, 2]):
print(key, value)
If the lengths differ, itertools.zip_longest fills the gaps instead of silently truncating.
while loops
count = 3
while count > 0:
print(count)
count -= 1
while True plus break is idiomatic for “read until the user is done”:
while True:
line = input("type q to quit: ")
if line == "q":
break
print(f"you typed: {line}")
Any while loop must contain something that eventually makes the condition false, or contain a break.
break, continue, and else
breakleaves the loop entirely.continueskips the rest of the current iteration.elseruns only if the loop finished without hittingbreak.
for n in [2, 4, 5, 6]:
if n % 2 != 0:
print(f"{n} is odd")
break
else:
print("all even")
# 5 is odd -> the else block is skipped
The else clause is most useful for search loops: break on a hit, handle “not found” in else without a flag variable.
match statements
For structural matching, match (3.10+) is clearer than a chain of elif:
match command.split():
case ["quit"]:
print("bye")
case ["load", filename]:
print(f"loading {filename}")
case _:
print("unknown command")
case _ is the catch-all. Note that match compares structure, not values with ==, and a bare name in a pattern captures rather than compares.
Common mistakes
1. Mutating a list while iterating it
items = [1, 2, 3, 4]
for item in items:
if item % 2 == 0:
items.remove(item) # index shifts; result depends on internals
Filter into a new list instead:
items = [item for item in items if item % 2 != 0]
2. Comparing values with is
a = 1000
b = 1000
a is b # False: different objects
a == b # True
Reserve is for singletons such as None, True, and False.
3. Forgetting to update the loop variable
A while loop whose condition never changes hangs the program. Ctrl+C interrupts it.
4. Mixing tabs and spaces
Python uses indentation as syntax. Standardize on four spaces and enable “convert tabs to spaces” in your editor.
5. Shadowing built-ins
list = [1, 2] breaks every later call to list(). Same for dict, str, id.
Summary
- Truthiness covers empty containers,
0, andNone; useis Nonefor missing values. foriterates values;enumerategives positions,rangegives counts,zippairs sequences.breakexits,continueskips, loopelseruns only withoutbreak.- Never add or remove items from a list you are iterating.
Next: strings, slicing, and formatting.