Skip to content
wannacode

Lists

Problem

Thirty grades

A teacher writes a program for the test scores. For five students they make five variables:

score1 = 62
score2 = 85
score3 = 47
score4 = 91
score5 = 78
total = score1 + score2 + score3 + score4 + score5
print(total)
Output
363

But the class has thirty students. Thirty variables, thirty terms to add. And the highest score needs twenty-nine more comparisons. The loop from the last lesson does not help: it cannot go through score1, score2, score3, because those are separate names. We need many values under one name.

The idea

A list: a row of boxes

A list is a row of values under one name. Each value, an element of the list, has a number: its index. Indexes start at 0. In Java and C# the same thing is called an array.

scores = [62, 85, 47, 91, 78]
print(scores[0])
print(scores[4])
print(len(scores))
scores[2] = 50
print(scores[2])
Output
62
78
5
50
  • The values go in square brackets [ ], separated by commas. You don't write a type. You can mix numbers and text in one list, but usually all the elements are of one kind.
  • scores[0] is the first element, scores[4] the fifth. The last index is always 1 less than the count.
  • len(scores) is the number of elements. Here it is 5.
  • scores[2] = 50 changes one element. The others stay the same.

If you don't know the values yet, but you know how many there are, you multiply a list holding one zero by the count:

booked = [0] * 3
booked[1] = 2
print(booked)
Output
[0, 2, 0]

Unlike arrays in Java and C#, a list grows. append adds an element at the end:

scores = [62, 85]
scores.append(47)
print(scores)
print(len(scores))
Output
[62, 85, 47]
3

print of a whole list shows its elements in [ ]. That is handy for checking, but for the program's output you usually print the elements yourself.

More precisely, if you are curious
  • A negative index counts from the back: scores[-1] is the last element, scores[-2] the one before it.
scores = [62, 85, 47, 91, 78]
print(scores[-1])
print(scores[-2])
Output
78
91

Try it

Which is which?

What will the program print?

prices = [12, 7, 30, 5]
print(prices[1] + prices[3])
Answer

The idea

A loop through the list

Now the loop does help. The counter i becomes the index: it goes from 0 to the last one and on every round takes scores[i].

scores = [62, 85, 47, 91, 78]
total = 0
for i in range(len(scores)):
total += scores[i]
print(f"Sum: {total}")
print(f"Average: {total / len(scores)}")
Output
Sum: 363
Average: 72.6

The counter goes through range(len(scores)): from 0 to len(scores) - 1, exactly the indexes. If you add all thirty grades in [ ], the loop does not change. This is called traversing the list.

/ in Python always gives a decimal number, so the average comes out as 72.6 with nothing extra. Integer division is //.

More precisely, if you are curious

Python also has ready-made functions for this: sum(scores) is the sum, max(scores) and min(scores) are the biggest and the smallest. Here we write them ourselves, so you can see how they work. That is also why the variable is total and not sum: this way the name sum stays free for the function.

scores = [62, 85, 47, 91, 78]
print(sum(scores), max(scores), min(scores))
Output
363 91 47

See it

The highest score

How do you find the biggest number? You remember the biggest one so far and replace it as soon as you see a bigger one.

scores = [62, 85, 47, 91, 78]
highest = scores[0]
for i in range(1, len(scores)):
if scores[i] > highest:
highest = scores[i]
print(highest) # 91
Step by step, in words
  1. Five scores, side by side. The numbers below are the indexes: from 0 to 4.
  2. highest starts from the first one: scores[0] is 62.
  3. i = 1: 85 > 62, so highest becomes 85.
  4. i = 2: 47 is not bigger than 85. Nothing changes.
  5. i = 3: 91 > 85, so highest becomes 91.
  6. i = 4: 78 < 91. range(1, len(scores)) is used up: the stop value 5 is not included, and the loop stops.
  7. The highest score is 91.

highest starts from the first element, not from 0. If all the scores were negative, 0 would "win" without being in the list. That is also why the loop starts from range(1, …): the first one is already in highest.

Try it

Find the bug

The program should print the sum 363. Instead it stops with an error:

Error
IndexError: list index out of range

Which line has the bug?

Pick the line with the bug.

The idea

for … in: for every element

When you need only the values and not the indexes, there is a shorter loop. How many students passed the exam (60 points or more)?

scores = [62, 85, 47, 91, 78]
passed = 0
for score in scores:
if score >= 60:
passed += 1
print(f"Passed the exam: {passed}")
Output
Passed the exam: 4

It reads "for each score in scores". This is the same for, except it goes straight through the elements of the list instead of the numbers from range. In Java the same thing is called for-each. There is no counter and no index, so you cannot go outside the list.

There is a limit too: you don't know which index you are at, and you cannot change the element.

More precisely, if you are curious
  • If you write score = 0 in the body, you change only the variable score. The list stays the same, and Python does not stop you:
scores = [62, 85, 47]
for score in scores:
score = 0
print(scores)
Output
[62, 85, 47]
  • To change elements, or when you need the index (for example for the neighbor scores[i + 1]), use a regular for.

Try it

Two names, one list

What will the program print?

prices = [10, 20, 30]
sale = prices
sale[0] = 5
print(prices[0])
Answer
More precisely, if you are curious

You make a real copy with a new list and a loop:

prices = [10, 20, 30]
sale = []
for price in prices:
sale.append(price)
sale[0] = 5
print(prices[0], sale[0])
Output
10 5

prices.copy() does the same:

prices = [10, 20, 30]
sale = prices.copy()
sale[0] = 5
print(prices[0], sale[0])
Output
10 5

Try it

Put the lines in order

The program should find the lowest price. Put its lines in order.

  1. print(lowest)
  2. lowest = prices[0]
  3. prices = [18, 7, 25, 12]
  4. for i in range(1, len(prices)):
  5. if prices[i] < lowest:
  6. lowest = prices[i]

Exercise

Working with a list

Solve the exercises in your editor. Each program first reads how many numbers there are, then the numbers themselves, one per line:

n = int(input())
numbers = []
for i in range(n):
numbers.append(int(input()))

1. Sum, even, odd. Print the sum of all the numbers, of the even ones and of the odd ones.

Input
3
1
2
3
Output
Sum: 6
Even: 2
Odd: 4

2. Reversed. Create a new list with the same numbers in reverse order and print it on one line.

Input
5
1
2
3
4
5
Output
5 4 3 2 1

3. Lowest, highest, average. In one pass through the list, without the ready-made min, max and sum.

Input
5
4
9
2
7
4
Output
Lowest: 2
Highest: 9
Average: 5.2

Exercise

Sorting and counting

4. Sorting. Sort the numbers from the smallest to the biggest. Hint: go through the list, and if two neighbors are in the wrong order, swap them (swapping is from the lesson on variables). Repeat until there is nothing left to swap. This is called bubble sort: the big numbers "bubble up" to the end. Don't use the ready-made numbers.sort(): the goal is to write it yourself.

Input
5
42
7
19
3
25
Output
3 7 19 25 42

5. Longest run. Find the longest run of equal numbers one after another.

Input
8
2
2
5
5
5
1
5
5
Output
The number 5, 3 times in a row

6. Grade statistics. Read grades from 2 to 6 and print how many there are of each kind. Hint: a list counts with 7 elements, where the grade is the index: counts[grade] += 1.

Input
8
6
4
5
6
3
2
6
5
Output
Excellent (6): 3
Very good (5): 2
Good (4): 1
Fair (3): 1
Poor (2): 1

More exercises

  • Median. The number in the middle of the sorted list. For 3, 1, 4, 1, 5 the median is 3. If there is an even count of numbers, the median is the average of the two in the middle: for 7, 1, 3, 9 it is (3 + 7) / 2 = 5.
  • Symmetric list. Does it read the same from front to back and from back to front? 1 2 3 2 1 is symmetric, 1 2 3 1 is not.
  • Roman numerals. Read a number from 1 to 3999 and print it in Roman numerals: 2024 is MMXXIV, 1994 is MCMXCIV. Hint: two lists side by side, with the values 1000, 900, 500, 400, 100, …, 1 and with the symbols "M", "CM", "D", "CD", "C", …, "I". While the number is at least the current value, add the symbol and subtract the value.

Test

Check yourself

1. In the list [62, 85, 47, 91, 78], at which index is 91?
2. What is the index of the last element of the list scores?
3. What is in the list right after booked = [0] * 3?
4. The loop is for i in range(len(scores) + 1): and it reads scores[i]. What happens?
5. sale = prices, then sale[0] = 5. What happens to prices[0]?

Made by Ivo Gergov as part of Evo Tech's campaign for accessible programming education ·