Drop links or images here to add them to the editor.

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.

Nested for loops

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:

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.

Nested while loops

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.

All together

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
Help! My code doesn't work!

Make sure that you check for the following things:

  • The inner loop is indented under the outer loop, and the code that uses both counters is indented under the inner loop.
  • The outer loop counts the rows and the inner loop counts the columns, and the item is picked out with the row first: array_name[row][column].
  • len(array_name) is the number of rows. The number of items on a row is len(array_name[row]).
  • In nested while loops the column counter is set back to 0 inside the outer loop, before the inner loop starts.
  • Both counters are increased, each inside its own loop.