Last 30 Days
No notifications
Loops let you repeat a block of code multiple times. Python provides two main loop types: for and while.
Iterates over a sequence (list, string, range, etc.):
for i in range(5):
print(i) # 0, 1, 2, 3, 4Repeats as long as a condition is True:
count = 0
while count < 5:
print(count)
count += 1| Statement | Description | ||||
break | Exit the loop immediately | ||||
continue | Skip current iteration, go to next | ||||
pass | Do nothing — placeholder | Useful Built-in Functions | Function | Purpose | Example |
range(n) | Generate numbers 0 to n-1 | range(5) → 0,1,2,3,4 | |||
range(a, b) | Generate numbers a to b-1 | range(2, 6) → 2,3,4,5 | |||
range(a, b, step) | With step | range(0, 10, 2) → 0,2,4,6,8 | |||
enumerate(seq) | Index + value pairs | enumerate(["a","b"]) → (0,"a"),(1,"b") | |||
zip(a, b) | Pair elements from two sequences | zip([1,2],["a","b"]) → (1,"a"),(2,"b") |
for i in range(3):
for j in range(3):
print(f"({i},{j})", end=" ")
print()The else block after a loop runs only if the loop did not exit via break:
for n in range(2, 10):
if n % 7 == 0:
print(f"Found {n}!")
break
else:
print("No multiples of 7 found")> Tip: Prefer for loops when the number of iterations is known. Use while when the termination depends on a dynamic condition.
Loops are how programs *do the same thing many times* — send 100 emails, scan 10,000 rows, retry until success. Python gives you two: for (iterate over a collection) and while (repeat while a condition holds). Master these and you've unlocked half of all real-world code.
A loop is a controlled jump back to an earlier line. Each cycle is an iteration. Python's loops are built on the iterator protocol — anything that knows how to give one item at a time can be looped.
for name in ["Anu", "Ben", "Cara"]:
print("hi", name)Unlike C/Java, Python's for doesn't count — it walks straight through items. Almost everything is iterable: lists, tuples, strings, dicts, sets, files, generators, ranges.
count = 3
while count > 0:
print(count)
count -= 1Use while when you don't know the iteration count upfront (retry loops, game loops, reading until EOF).
range(5) # 0,1,2,3,4
range(2, 8) # 2,3,4,5,6,7
range(0, 10, 2) # 0,2,4,6,8
range(10, 0, -1) # countdownrange is lazy — range(10**9) uses negligible memory because numbers are computed on demand.
for n in nums:
if n < 0:
continue # skip this iteration
if n > 100:
break # exit the loop
process(n)
else:
print("loop finished without break")The loop's else runs only if the loop *wasn't* broken — useful for search loops.
1. for i in range(len(items)): then items[i]. Just write for item in items. Use enumerate if you need the index.
2. Modifying a list while iterating it. Items get skipped or repeated. Iterate a copy (for x in items[:]) or build a new list.
3. Infinite while with no exit. Forgot to update the loop variable? Hang. Always make sure progress is guaranteed.
4. Using == to test floats in a while. Floating-point drift means the condition may never be exactly hit. Use <= / >= or a tolerance.
5. while True: break forests. Re-think the condition; usually a single boolean expression is cleaner.
6. Building a list with += [x] in a loop. Use .append(x) (faster, clearer) or a list comprehension.
for i, name in enumerate(names, start=1):
print(i, name)for name, score in zip(names, scores):
print(name, score)
for x in reversed(items):
...
enumerate → (index, value) pairs.zip → parallel iteration; stops at the shortest. Use itertools.zip_longest to pad.reversed → walks back-to-front without copying.squares = [x*x for x in range(10)]
evens = [x for x in nums if x % 2 == 0]
pairs = [(x, y) for x in xs for y in ys if x != y]
lengths = {name: len(name) for name in names}
uniques = {x.lower() for x in tags}List / dict / set comprehensions are faster than for + append because the loop runs in C. Keep them readable — if it needs more than two clauses or nested ifs, use a regular for.
it = iter([10, 20, 30])
next(it) # 10
next(it) # 20
next(it) # 30
next(it) # raises StopIterationA for loop is just sugar over this. Anything that defines __iter__ and __next__ is iterable — your custom classes can plug straight into for.
def squares_up_to(n):
for i in range(n):
yield i * ifor s in squares_up_to(1_000_000):
if s > 100:
break
yield pauses the function; the next iteration resumes it. Generators stream values one at a time — huge memory savings on big data.
Generator *expressions* mirror comprehensions with parentheses: sum(x*x for x in nums).
The itertools standard module provides battle-tested building blocks:
from itertools import chain, islice, groupby, accumulate, product, combinationsfor x in chain(list_a, list_b): ... # concatenate iterables
for x in islice(stream, 100): ... # first 100 of a stream
for key, group in groupby(rows, key=...): # SQL-style grouping (requires sorted input)
for total in accumulate(nums): # running sum
for a, b in product(xs, ys): ... # cartesian product
for combo in combinations(items, 3): ... # all 3-element subsets
If you ever feel like writing nested loops with index math, check itertools first.
append = lst.append; for x in items: append(x*2)).any() / all() with generator expressions for short-circuit checks: if any(x < 0 for x in nums): ....collections.Counter and grouping loops with defaultdict(list).async for)When iterating over an async stream (websocket, HTTP responses, DB rows):
async for message in websocket:
await handle(message)This is non-blocking — other coroutines can run between iterations. Pairs with async def and await. (Covered in depth alongside concurrency.)
1. Sum 1…100 using for + range, then again with sum(range(...)) and compare line counts.
2. Use enumerate to print "1. Anu, 2. Ben, ..." from a list of names starting at 1.
3. Convert this loop into a list comprehension: out = []\nfor x in nums:\n if x > 0: out.append(x*2).
4. Write a generator fib() that yields Fibonacci numbers forever, then take the first 20 with itertools.islice.