While loops
A for loop runs once per item. A while loop runs as long as a condition
is true, which is what you need when you do not know in advance how many
times to go round.
stock = 2
while stock < 10:
stock += 3
print("Restocked to", stock)
print("Done")
Before each round Python checks stock < 10. If true, the block runs; if
false, the loop ends and the program continues after it. Here it runs three
times: 5, 8, 11.
Counting with while
Anything for with range can do, while can do with a counter, though
for is shorter when the count is known.
i = 0
while i < 3:
print("Box", i)
i += 1
The i += 1 is essential. Without it the condition never changes.
The infinite loop
Delete the i += 1 line above and run it. The condition i < 3 stays true
forever, so the loop never ends. The output box fills with "Box 0", and this
site stops the program after ten seconds. A real program would run until you
killed it.
Press Stop if you get tired of waiting. Every while loop needs something
in its body that eventually makes the condition false. When a program hangs,
that missing line is the first thing to look for.
Leaving early with break
break ends the loop immediately, whatever the condition says. It is the
usual way to write "loop until something is found":
prices = [40, 25, 60, 2.5]
i = 0
while i < len(prices):
if prices[i] > 50:
print("First expensive item is at position", i)
break
i += 1
break works in for loops too. Inside a function there is a second way
out: return ends the whole function at once, loop included, which is
often the neatest way to write "return the first one that matches".
Which loop?
Use for when you are going through items or a known number of times. Use
while when the number of rounds depends on what happens inside the loop:
halving until small enough, retrying until it works, reading until the end.
Try it
Restock until full
Deliveries arrive in boxes of box loaves. Write deliveries_needed(stock, box, target)
that returns how many boxes must be added before stock reaches at least
target. If stock already meets the target, return 0.
deliveries_needed(2, 3, 10) -> 3 (2 -> 5 -> 8 -> 11)
deliveries_needed(10, 3, 10) -> 0
def deliveries_needed(stock, box, target):
boxes = 0
while ...:
...
return boxes
Halve until under
A price is cut in half repeatedly until it is below limit. Write
halvings(price, limit) that returns how many halvings that takes. If the
price is already below the limit, return 0.
halvings(100, 10) -> 4 (100 -> 50 -> 25 -> 12.5 -> 6.25)
halvings(5, 10) -> 0
def halvings(price, limit):
...
First item over a price
Write first_over(prices, limit) that returns the position of the first
value in prices that is greater than limit, or -1 if there is none.
first_over([40, 25, 60, 2.5], 50) -> 2
first_over([40, 25], 50) -> -1
def first_over(prices, limit):
i = 0
while i < len(prices):
...
i += 1
return -1
Next: Dictionaries.