Reference · module 3
Lists and loops
Everything this module explains, on one page.
Lists
Hold several values under one name and reach any of them.
- Square brackets make a list: names = ["Anna", "Ben", "Cleo"]. One name now holds three values in a fixed order, and len(names) is 3.
- Reach one with names[0], and that zero is not a mistake: the first item is at 0, the second at 1, the third at 2. The last index is always len minus one.
- Which makes names[3] an IndexError on a list of three. Counting backwards is easier: names[-1] is the last one, whatever the length, and names[-2] the one before it.
The mistake you are about to make
names[3] on a list of three
names[-1]
With three items the third one ought to be number 3. Counting starts at zero, so the last index is always one less than the length. Safer: count from the end.
Changing a list
Add to a list, take from it, and cut a piece out.
- xs.append(4) puts 4 on the end. The dot means ask this list to do something, and append changes the list itself rather than handing back a new one.
- That is worth saying plainly: after xs.append(4) the name xs holds a longer list. Nothing needs to be assigned back, and writing xs = xs.append(4) is a classic mistake that stores None.
- A slice takes a piece: xs[1:3] gives the items at 1 and 2. The first number is included and the second is not, which is the same rule range follows.
The mistake you are about to make
xs = xs.append(4)
xs.append(4)
Functions return their result — except this one. Append changes the list in place and returns None, so assigning it back throws the list away.
for
Do the same thing to every item.
- for name in names: runs the indented lines once for each item, with name holding a different one each time. Same colon, same indentation as an if.
- range(3) gives 0, 1, 2 — three numbers, and the 3 itself is not among them. It is the same rule as a slice: the end is where it stops, not the last one it reaches.
- The loop variable is an ordinary name and you choose it. Call it what the items are — for name in names, for price in prices — and the loop reads as a sentence.
The mistake you are about to make
range(3) → 1, 2, 3
range(3) → 0, 1, 2
Three sounds like up to and including three. Range gives three numbers starting at zero: the end is where it stops, not the last one reached.
while
Repeat until something changes, and make sure it does.
- while n < 5: repeats for as long as the condition holds. Where for walks through items that are already there, while repeats until something becomes true.
- Which puts one duty on you: something inside the loop has to change what the condition looks at. If nothing does, the condition stays true and the program runs forever.
- break leaves the loop immediately, whatever the condition says. It is the honest way out of a loop whose ending is easier to spot from inside than to write into the condition.
The mistake you are about to make
while n < 5: — with n never changing
n = n + 1 inside the loop
The condition is checked again every time round, and it does not change itself. If nothing inside moves n, it stays true forever and the program never ends.
Building a result
Use a loop to produce one answer instead of printing many.
- Most loops are not for printing, they are for building. Start with a name holding an empty answer, change it once per item, and read it after the loop has finished.
- For a sum that is total = 0 before the loop and total = total + x inside it. The starting value matters: begin at 1 and every answer is one too big.
- The same shape builds a list: result = [] before, result.append(something) inside. And the reading line goes AFTER the loop, at no indentation — inside, it would print a running total.
The mistake you are about to make
print(total) inside the loop
print(total) after the loop, no indent
The line that reads the answer ends up inside the loop and prints a running total, once per item. It belongs after the loop, and the indent is what decides.