That Blue Square Thing

Computer Science GCSE

Lists of Lists

Lists are collection data types - sometimes called arrays in general programming terms.

A list can include other lists - so you get a list of lists. This is known as a two-dimensional array. They can get quite complex but are also super useful.

Note that in all the examples here I'm using file reading to read in a list of lists from a text file. This is simply because it's quicker to do that than it is to type up the list each time! Details on exactly how to do this are on the Read/Write Files page - which I'd recommend you read first.

Getting Data from Lists of Lists

So, there's a list of songs. Say I want just the songs which are Dance tunes (ones with DA next to them), how do I do that?

Here's a strategy:

  1. read in the whole list into a list of lists - as above
  2. set up an empty list called danceSongs to store the DA tunes on
  3. use a for loop to look at each song in turn - passing each song into a temporary variable called currentSong
  4. look at the second element in currentSong (index 1 remember)
  5. if this element is "DA" then add the song to the list of Dance tracks
  6. otherwise do nothing

Let's see how this would work:

# code to pick out just dance tracks

import csv # import csv module

with open("readinfile.txt", newline="") as inputfile:
songs = list(csv.reader(inputfile))

danceSongs = [ ]

for i in range(0, len(songs)): # look at one line at a time
currentSong = songs[i]
if currentSong[1] == "DA":
danceSongs.append(currentSong) # add to the list

for i in range(0, len(danceSongs)): # print one line at a time
print(danceSongs[i])

Once you can do this you can look through lists of lists without too much trouble. The ley is to think about writing to a new list each time you want to find something specific. You can then iterate over that list to pull out the data you actually need.

Deleting Data from Lists of Lists

The .remove Python method will remove the first instance of an item from a list. Just the first item though, so if your lists has the same item more than once you need to be a little careful.

Say this time I want to delete all the Dance tracks from my list. Here's a strategy for that:

  1. read in the whole list into a list of lists - as above
  2. set up an empty list called danceSongs to store the DA tunes on
  3. use a for loop to look at each song in turn - passing each song into a temporary variable called currentSong
  4. create the list of danceSongs as in the example above
  5. use a for loop to iterate over danceSongs one item at a time
  6. for each item remove it from the songs list - the original one you read in

Here's code to do that.

# code to delete just dance tracks

import csv # import csv module

with open("readinfile.txt", newline="") as inputfile:
songs = list(csv.reader(inputfile))

danceSongs = [ ]

for i in range(0, len(songs)): # look at one line at a time
currentSong = songs[i]
if currentSong[1] == "DA":
danceSongs.append(currentSong) # add to the list

for i in range(0, len(danceSongs)): # remove dance songs
songs.remove(danceSongs[i])

for i in range(0, len(songs)): # print what's left
print(songs[i])

The idea of creating a new list of things to delete and then using it to iterate over the original list and delete them is a really powerful one.

Find items from a list based on numbers

This adds a touch of complication to the idea of findings a song. Mainly because you need to appreciate that the list items being read in appear as strings. So, using numbers is a touch more difficult.

Say I want to find songs from 2006 and earlier only from the list. Here's how to do that.

# code to find songs from 2006 and earlier

import csv # import csv module

with open("readinfile.txt", newline="") as inputfile:
songs = list(csv.reader(inputfile))

oldSongs = [ ]

for i in range(0, len(songs)): # look at one line at a time
currentSong = songs[i]
currentYear = int(currentSong[3])
if currentYear < 2007:
oldSongs.append(currentSong) # add to the list

for i in range(0, len(oldSongs)): # print one line at a time
print(oldSongs[i])

The trick here is to remember to deal with the integer properly.

Find a single item in a List of Lists

This is reasonably straight forward to do in the same way as the other examples on this page, but there is a slightly more efficient way to do it.

the key is realise that you don't need to look at every item in the list. If, for example, you find the item straight away then there's no need to look at every item after it. This means a for loop is less effective - in this case we really want a while loop instead, with the intention of getting out of the while loop as soon as the item is found.

Here's how to do that.

# code to find a specific item in a list

import csv # import csv module

with open("readinfile.txt", newline="") as inputfile:
songs = list(csv.reader(inputfile))

search = input("Enter the name of the song to search for: ")

found = False # variable to signify when item is found
i = 0 # variable used as index of list

while not(found):
currentSong = songs[i]
if currentSong[0] == search:
found = True
else:
i = i + 1 # move index on to next item in list

print("Found: " + search + " at index number " + str(i))

This works - but only if you spell the name of the song exactly right (including the capitalisation).

To solve the issue with capitals you could use:

if currentSong[0].upper() == search.upper():

This will search an uppercase version of the song title, which will solve that part of the problem.

The problem of the song not existing at all in the list will still be a problem however. To solve this you need to exit the while loop when i is equal to the legnth of the list or when the song is found. This means changing the while condition to:

while not(found) and i < len(songs):

The condition here means that you want to execute the loop whilst both of the parts of the condition are True - i.e. you haven't found the song and i is still less than the length of the list. Once either of these things stops being True the loop exits.

There's just one more change to add - the message at the end won't make sense if the song isn't in the loop. The full code for the revised version is here:

# improved code to find a specific item in a list

import csv # import csv module

with open("readinfile.txt", newline="") as inputfile:
songs = list(csv.reader(inputfile))

search = input("Enter the name of the song to search for: ")

found = False # variable to signify when item is found
i = 0 # variable used as index of list

while not(found) and i < len(songs):
currentSong = songs[i]
if currentSong[0].upper() == search.upper():
found = True
else:
i = i + 1 # move index on to next item in list

if found:
print("Found: " + search + " at index number " + str(i))
else:
print(search + " can not be found in the list of songs.")

The sorts of thinking going in to this are about where you need to be to get high marks at GCSE. Thinking about problems such as capitalisation, not wanting to search the entire list, dealing with input errors and customising the output properly are perfect at this level.