Loops

In this guide you’ll learn how to repeat actions in Python with while and for. You’ll also learn how break, continue, and the special else on loops work. The examples are simple and practical.

Why loops matter

Loops help you run the same code many times. They save time, reduce mistakes, and make programs clear. You can use loops to process a list of items, read user input until a keyword, or search for something inside data.

When to use each loop

TIP: If you can count or iterate through items, prefer for. If you are waiting for a condition (e.g., user types stop), prefer while.

while: repeat while a condition is true

Structure:

while <condition>:
    # repeated code

The loop stops when the condition becomes False.

Example A — Keep doubling until the number is large enough

n = 6
while n <= 100:
    print(n)
    n *= 2
print("Done")

What happens? Prints 6, 12, 24, 48, 96 and then stops. We updated n each time; this prevents an infinite loop.

Example B — Sentinel loop with break and continue

Ask for words until the user types stop. Ignore very short words.

while True:
    word = input("Word (type 'stop' to finish): ")
    if word == "stop":
        break              # leave the loop completely
    if len(word) < 3:
        continue           # skip the rest of this round
    print("Accepted:", word)

The else block runs only if the loop ended normally (condition became False) and no break was used.

numbers = [3, 5, 12, 7]
index = 0

while index < len(numbers):
    if numbers[index] < 0:
        print("Found a negative:", numbers[index])
        break
    index += 1
else:  # executed only if we never broke out
    print("No negatives found")

IDEA: Think of else as a “break checker.” If you never break, else runs.

for: go through items in a sequence

Structure:

for item in <iterable>:
    # use item

Example A — Shopping list with continue and break

items = ["bread", "apples", "sugar", "eggs", "tea"]

for item in items:
    if item == "sugar":
        continue              # skip sugar
    print("Buy:", item)
    if item == "eggs":
        print("Got eggs — stopping early.")
        break                 # stop the whole loop

for ... else: run only if loop didn’t break

word = "piano"
for ch in word:
    if ch == "z":
        print("Found a 'z'.")
        break
else:
    print("No 'z' found.")

USE CASE: Searching. If you don’t find what you want (no break), the else part confirms that.

range(): number streams for counting

range() produces numbers on demand (it doesn’t build a big list by default).

for i in range(1, 4):   # 1, 2, 3
    print(i)

print(list(range(5)))            # [0, 1, 2, 3, 4]
print(list(range(10, 0, -2)))    # [10, 8, 6, 4, 2]

REMEMBER: the stop value is excluded.

Helpful patterns

Get index and value with enumerate

letters = "data"
for pos, ch in enumerate(letters):
    print(pos, ch)

Nested loops (a small grid)

for r in range(2):
    for c in range(3):
        print(f"({r},{c})")

Simple countdown

for seconds in range(3, 0, -1):
    print(seconds)
print("Lift-off!")

enumerate

enumerate() is a built-in Python function that lets you loop over a sequence and get both the index and the value at the same time.

enumerate(iterable, start=0)

List with default indexing (starts at 0)

fruits = ["apple", "banana", "pear"]
for i, fruit in enumerate(fruits):
    print(i, fruit)
# 0 apple
# 1 banana
# 2 pear

Start counting from 1 (useful for line numbers)

lines = ["first", "second", "third"]
for line_no, text in enumerate(lines, start=1):
    print(f"Line {line_no}: {text}")
# Line 1: first
# Line 2: second
# Line 3: third

String characters with positions

for pos, ch in enumerate("data"):
    print(pos, ch)
# 0 d
# 1 a
# 2 t
# 3 a

See the pairs directly

list(enumerate("cat"))
# [(0, 'c'), (1, 'a'), (2, 't')]

Why use enumerate() instead of range(len(...))?

This:

for i in range(len(fruits)):
    print(i, fruits[i])

works, but is less readable and easier to make mistakes with. Prefer:

for i, fruit in enumerate(fruits):
    print(i, fruit)

The walrus operator := (Python 3.8+)

The walrus operator assigns and returns a value in one expression. Use it when it makes code clearer, not just shorter.

# Keep reading words until the user enters a blank line
while (word := input("Word (blank to stop): ")) != "":
    print(f"You typed: {word}")
numbers = [12, -3, 7, 0, 15]
for n in numbers:
    if (gap := 10 - n) >= 0:
        print(f"{n} fits; {gap} space left.")

Common mistakes (and quick fixes)

Recap