Computers are good at doing the same thing many times without getting bored. Loops are how you ask them to.
for over a collection#
A for loop takes each item of something in turn:
for fruit in ["apple", "banana", "cherry"]:
print(fruit)
for letter in "hey":
print(letter) # h, e, y on separate lines
The name after for (here fruit) refers to the current item on each round.
range: counting#
range produces a run of whole numbers:
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(2, 6): # 2, 3, 4, 5
print(i)
for i in range(10, 0, -2): # 10, 8, 6, 4, 2
print(i)
Like slicing, the end is not included. range(5) has five numbers, 0 to 4, which are exactly the valid positions of a list of five things.
Adding things up#
The most common loop of all keeps a running total:
numbers = [4, 8, 15, 16, 23, 42]
total = 0
for x in numbers:
total += x
print(total) # 108
The same shape finds a largest value, counts matches, or builds a new list. (Python also has sum(numbers) and max(numbers) built in, but you need to know the loop they are hiding.)
Position and value together#
When you need both the index and the item, use enumerate:
for i, name in enumerate(["Asha", "Ravi", "Meera"]):
print(i, name) # 0 Asha / 1 Ravi / 2 Meera
That is clearer than for i in range(len(names)): followed by names[i].
while: until something happens#
When you do not know in advance how many rounds there are, loop while a condition holds:
n = 4071
digits = 0
while n > 0:
n //= 10
digits += 1
print(digits) # 4
Something inside a while must move it towards stopping. If nothing changes, the loop runs forever. Press Ctrl+C to stop a runaway program.
break and continue#
break leaves the loop at once. continue skips to the next round.
for x in [3, 8, -1, 5]:
if x < 0:
print("found a negative")
break
print(x)
# prints 3, 8, then "found a negative"; 5 is never reached
for x in range(10):
if x % 2 == 1:
continue
print(x) # 0 2 4 6 8
Loops inside loops#
A loop can sit inside another. The inner one runs completely for every round of the outer:
for row in range(1, 4):
for col in range(1, 4):
print(row * col, end=" ")
print()
# 1 2 3
# 2 4 6
# 3 6 9
end=" " tells print to finish with a space instead of a new line.
Be careful with size: two nested loops over n items do n × n steps. For 1,000 items that is a million, which is fine; for 100,000 it is ten billion, which is far too slow. Much of algorithms is finding a way to do one pass instead of two.
Key points#
for x in collectionvisits each item;range(a, b)counts fromaup to, not including,b.enumerategives position and item together.whilerepeats while a condition is true, and something inside must change it.breakleaves the loop;continueskips to the next round.- Nested loops multiply the work.
Next: packaging code into reusable functions.