In the Lists chapter one for loop was enough to visit every item in a list. The counter went from 0 up to the last index, and the loop printed one item each time round.
A 2D array needs two counters: one for the row and one for the column. So it needs two loops, one inside the other: a nested loop, as in the String manipulation chapter, where an outer loop went through a list of words and an inner loop through the letters of each one.
animals = [["Salmon", "Pollock", "Cod"],
["Parrot", "Duck", "Wren"],
["Camel", "Lion", "Tiger"]]
for row in range(0, len(animals)):
for column in range(0, len(animals[row])):
print(animals[row][column])
The outer loop runs once for every row. Every time it does, the inner
loop runs all the way through that row, once for every column. The print
is indented twice, so it is inside both loops.
animals = [["Salmon", "Pollock", "Cod"],
["Parrot", "Duck", "Wren"],
["Camel", "Lion", "Tiger"]]
for row in range(0, len(animals)):
print("Row " + str(row))
for column in range(0, len(animals[row])):
print(animals[row][column])
Run it and watch the order. row is 0 while column goes 0, 1, 2. Only once
the inner loop has finished does the outer loop move on, and then column
starts again from 0 for row 1. Three rows of three items make nine prints
from inside the inner loop, and three Row lines from the outer loop.
Two different lengths are at work here:
len(animals) is the number of rows, 3, because the outer list holds
three rows.len(animals[row]) is the number of items on one row. Here every row has
3, but a row that has been appended to would have more, and the inner loop
would follow it.Where every row is known to be the same length, a fixed number works too, as in
range(0, 3). The loop just no longer adapts if the array changes.
The same job can be done with two while loops, each with a counter you build
yourself:
row = 0
while row < len(animals):
column = 0
while column < len(animals[row]):
print(animals[row][column])
column = column + 1
row = row + 1
Each counter is created, compared and increased, the three places a counter
always needs in a while loop. The one that is easy to miss is where column
is reset: column = 0 is inside the outer loop, so it happens again at the
start of every row.
Put column = 0 above the outer loop instead and the program prints the first
row and nothing more. After row 0, column is already 3, so the inner loop’s
condition is false straight away for every row that follows. A for loop
cannot make this mistake, because it starts its counter again by itself.
| Technique | What it does | Python example |
|---|---|---|
| Initialise a 2D array | Creates a new 2D array. | array_name = [["item 1", "item 2", "item 3"], ["item 4", "item 5", "item 6"]] |
| Output item | Outputs a single item from the array. | print(array_name[down_index][across_index])
print(animals[1][2]) |
| Edit item | Changes or replaces an item in the array. | array_name[down_index][across_index] = new data
animals[0][2] = "Plaice" |
| Append | Adds an item to the end of a row. | array_name[down_index].append(new data)
animals[0].append("Trout") |
| Append using a loop | Keeps adding new items to a row until the user wants to stop. | words = [[], []]
words_left = True
while words_left:
print("Enter a word")
word = input()
words[0].append(word)
print("Would you like to enter another word? Y/N")
answer = input().upper()
if answer == "N":
words_left = False |
| Find the index | Gets the index number of an item of data on one row. | print("Which word would you like to find?")
word = input()
location = words[0].index(word) |
| Output all items: for loop | Outputs every item in the array one by one using nested loops. | for row in range(0, len(array_name)):
for column in range(0, len(array_name[row])):
print(array_name[row][column]) |
| Output all items: while loop | Does exactly the same as above, but with nested while loops. | row = 0
while row < len(array_name):
column = 0
while column < len(array_name[row]):
print(array_name[row][column])
column = column + 1
row = row + 1 |
Make sure that you check for the following things:
array_name[row][column].len(array_name) is the number of rows. The number of items on a row is
len(array_name[row]).while loops the column counter is set back to 0 inside the
outer loop, before the inner loop starts.