The Python for loop takes the items of an iterable one at a time, assigns each to a loop variable and runs the loop body for it, so it repeats once per item in a list, tuple, dictionary, set, string or range(). Python has no C-style counting loop; counting is done by looping over range().
names = ["alex", "brian", "charles"]
for name in names:
print("Current name is:", name)
Current name is: alex
Current name is: brian
Current name is: charles
We loop over each built-in collection, get indexes with enumerate(), walk two lists with zip(), use for … else, and avoid changing a list while looping over it. The examples run on Python 3.14.
1. Syntax
The loop variable takes the next value at the start of each pass, and the loop ends when the iterable has no more items. The variable keeps its last value after the loop, but it is never assigned when the iterable is empty.
for val in iterable:
statements
2. Looping over Lists, Tuples, Sets and Strings
Every iterable works the same way. A tuple keeps its order like a list, a set has no guaranteed order, and a string yields its characters.
for e in ("item1", "item2"):
print("tuple:", e)
for c in "hey":
print("char:", c)
total = 0
for price in {4, 2, 9}:
total += price # total = 15, the order does not matter for a sum
tuple: item1
tuple: item2
char: h
char: e
char: y
3. Looping over a Dictionary
Looping over a dictionary yields its keys. The items() method yields key-value pairs, which we unpack into two loop variables.
stock = {"tea": 4, "milk": 0, "rice": 9}
for item, qty in stock.items():
print(f"{item}: {qty}")
tea: 4
milk: 0
rice: 9
Dictionaries keep insertion order since Python 3.7, so the loop visits the keys in the order they were added. The values() method yields only the values.
4. Counting with range()
To repeat a block a fixed number of times, or to loop over numbers, we use range(). The stop value is not included.
for i in range(3):
print("lap", i)
lap 0
lap 1
lap 2
5. Indexes with enumerate() and Pairs with zip()
When we need the position too, enumerate() yields index-value pairs and replaces the error-prone range(len(items)). The zip() function walks several iterables side by side and stops at the shortest one; strict=True (Python 3.10+) raises an error on a length mismatch instead.
for pos, name in enumerate(names, start=1):
print(pos, name)
for name, score in zip(names, [90, 85, 77]):
print(name, score)
1 alex
2 brian
3 charles
alex 90
brian 85
charles 77
6. break, continue and for … else
The break statement ends the loop, continue skips to the next item, and an else block runs only when the loop finished without break, which is useful for search loops.
for name in names:
if name.startswith("z"):
print("found", name)
break
else:
print("no name starts with z") # this line runs
7. Do Not Change a List While Looping over It
Removing items from the list we loop over makes the loop skip elements, without any error or warning. We build a new list instead, or loop over a copy.
nums = [1, 2, 2, 3]
for n in nums:
if n == 2:
nums.remove(n)
wrong = nums # [1, 2, 3], one 2 survived
nums = [1, 2, 2, 3]
right = [n for n in nums if n != 2] # [1, 3]
Changing the size of a dictionary or set during a loop raises RuntimeError instead, which at least makes the problem visible.
8. Summing an Order with Nested Data
Real data is often a list of dictionaries. A single loop with unpacking and a running total handles an order with quantities and prices.
order = [{"item": "tea", "qty": 2, "price": 4.5}, {"item": "rice", "qty": 1, "price": 12.0}]
total = 0
for line in order:
total += line["qty"] * line["price"]
# total = 21.0
The same total fits in one expression, sum(line[“qty”] * line[“price”] for line in order), which is the usual style once a loop only accumulates a value.
9. for Loop FAQs
Developers coming from Java or C loops look for reverse loops, uneven lists and comprehensions.
9.1. How do we loop backwards?
We wrap the sequence in reversed(), for name in reversed(names):, or count down with range(len(names) – 1, -1, -1). The first form is easier to read.
9.2. How do we loop over two lists of different lengths?
The zip() function stops at the shorter one. To go on to the end of the longer list, itertools.zip_longest() fills the gaps with a value we choose.
9.3. When should we use a list comprehension instead of a loop?
When the loop only builds a new list from an old one, a comprehension such as [n * 2 for n in nums] is shorter. Loops are better when the body has several steps or side effects.
10. Conclusion
A for loop visits each item of an iterable once. We use items() for dictionaries, range() for counting, enumerate() for indexes and zip() for parallel lists, and we build a new list instead of changing the one we loop over.
11. References
Happy Learning !!