Programs on a List You Read
Every list program so far has been handed its data by you, on the first line. Real questions do not say that — they say “accept a list from the user and…”. Nothing new is needed: the reading half is one of the two shapes from the last two pages, the working half is a loop you have already written, and the whole program is the two of them one after the other.
1Every program on this page has the same three parts
Ask the count and append that many times, or take the whole list with eval(). This half never changes.
The loop from the programming pages: a collector above it, a test inside it. This half is the question.
Print the list back as well as the answer, so the user can see what the program actually got.
2Program 1 — total and average of marks the user types
Ask how many marks there are, read them one at a time, and print the total and the average.
- the count,
n - then
nmarks
- append each mark to a list
- add the list up in a second loop
- the list, the total and the average
# read a list of marks, then report the total and the average
n = int(input('How many marks? '))
marks = []
for i in range(n):
value = int(input('Enter mark ' + str(i + 1) + ': '))
marks.append(value)
total = 0
for m in marks:
total = total + m
print('The marks are', marks)
print('Total:', total)
print('Average:', total / len(marks))How many marks? 4 Enter mark 1: 72 Enter mark 2: 65 Enter mark 3: 88 Enter mark 4: 91 The marks are [72, 65, 88, 91] Total: 316 Average: 79.0
for i in range(n):The reading loop. It ends before the working loop begins — the list has to be complete before anything can be asked about it.
for m in marks:The working loop, over the list that now exists. Two loops one after the other, not one inside the other: the first fills the list, the second reads it.
3Program 2 — largest and smallest, from a list typed in one go
Take a whole list with eval() and report its largest and smallest values, without max() or min().
# read a whole list at once, then find the largest and the smallest
numbers = eval(input('Enter a list of numbers: '))
largest = numbers[0]
smallest = numbers[0]
for n in numbers:
if n > largest:
largest = n
if n < smallest:
smallest = n
print('Largest:', largest)
print('Smallest:', smallest)Enter a list of numbers: [45, 88, 12, 91, 67] Largest: 91 Smallest: 12
Three lines of reading became one. The champions still start at numbers[0] — and now that the list came from a user, that line is also the program's first assumption: there is at least one item. Section 7 is about what happens when there is not.
4Program 3 — split what the user typed into evens and odds
Read a list of numbers and print the even ones and the odd ones as two separate lists.
# read a list, then split it into evens and odds
n = int(input('How many numbers? '))
numbers = []
for i in range(n):
numbers.append(int(input('Enter number ' + str(i + 1) + ': ')))
evens = []
odds = []
for value in numbers:
if value % 2 == 0:
evens.append(value)
else:
odds.append(value)
print('You entered:', numbers)
print('Evens:', evens)
print('Odds: ', odds)How many numbers? 5 Enter number 1: 12 Enter number 2: 7 Enter number 3: 30 Enter number 4: 45 Enter number 5: 8 You entered: [12, 7, 30, 45, 8] Evens: [12, 30, 8] Odds: [7, 45]
Note the reading loop here appends in one line — numbers.append(int(input(...))) — rather than storing the value in value first. Both are correct; the two-line version is easier to read and easier to put a print() into when something goes wrong. Also note that the loop variable is called value in the second loop and i in the first: one is an item, the other is a position, and the names should say so.
5Program 4 — search the list the user typed
Read a list and a value to look for, and report the position — or that it is not there.
# read a list, then search it for a value the user asks for
numbers = eval(input('Enter a list: '))
wanted = int(input('Which number are you looking for? '))
for i in range(len(numbers)):
if numbers[i] == wanted:
print(wanted, 'found at position', i)
break
else:
print(wanted, 'is not in the list')Enter a list: [45, 88, 12, 91] Which number are you looking for? 12 12 found at position 2
Enter a list: [45, 88, 12, 91] Which number are you looking for? 50 50 is not in the list
Two inputs of different kinds, which is the only new thing here: eval() for the list, plain int(input()) for the single value. Using eval() for both would work and is worth avoiding — the second answer is one number, and int() is the honest way to read one number.
6Program 5 — the names, numbered, in reverse
Read a list of names and print them numbered from 1, last one first.
# read a list of names and print them numbered, in reverse order
n = int(input('How many names? '))
names = []
for i in range(n):
names.append(input('Enter name ' + str(i + 1) + ': '))
print('In reverse:')
for i in range(len(names) - 1, -1, -1):
print(len(names) - i, names[i])How many names? 3 Enter name 1: Asha Enter name 2: Ravi Enter name 3: Meera In reverse: 1 Meera 2 Ravi 3 Asha
int() anywhere in the reading loop. A name is text and must stay text — casting it would raise ValueError on the first name typed. The only int() in the program is round the count, which really is a number.The printing loop walks backwards — len(names) - 1 down to 0 — while the label counts forwards: len(names) - i is 1 when i is 2, and 3 when i is 0. Two counters running in opposite directions off one loop variable, which is a thing only the index form can do.
7Program 6 — how many of the user's marks beat the average?
Read the marks, work out the average, and count how many are above it.
# read a list and report how many marks are above the average
n = int(input('How many marks? '))
marks = []
for i in range(n):
marks.append(int(input('Enter mark ' + str(i + 1) + ': ')))
total = 0
for m in marks:
total = total + m
average = total / len(marks)
above = 0
for m in marks:
if m > average:
above = above + 1
print('Average:', average)
print('Above average:', above)How many marks? 4 Enter mark 1: 72 Enter mark 2: 65 Enter mark 3: 88 Enter mark 4: 91 Average: 79.0 Above average: 2
Three loops, and each one has to finish before the next can start. Read them all; only then can the total be complete; only then does the average exist; only then can anything be compared with it. This is the two-pass program from the counting page with a reading pass in front of it.
8The answer that breaks every program here
The user types 0 for the count, or presses Enter on []. The reading loop runs no rounds, the list is empty, and every program on this page then fails in its own way:
total / len(marks)ZeroDivisionError: division by zero — there is nothing to divide by.
largest = numbers[0]IndexError: list index out of range — there is no first item to make a champion of.
max(marks)ValueError: max() iterable argument is empty — even the built-in cannot answer.
if. if len(marks) == 0: before the working part, printing something honest like “no marks were entered”, and the rest of the program under the else. It is one line of thought that separates a program that works from a program that works when the user cooperates.# the same program, with the empty list dealt with
n = int(input('How many marks? '))
marks = []
for i in range(n):
marks.append(int(input('Enter mark ' + str(i + 1) + ': ')))
if len(marks) == 0:
print('No marks were entered, so there is nothing to work out')
else:
total = 0
for m in marks:
total = total + m
print('Average:', total / len(marks))How many marks? 0 No marks were entered, so there is nothing to work out
9Recap
The reading loop finishes before the working loop starts. Two loops one after the other, never one inside the other.
Count-then-append, or one eval(). Whatever the question asks about the list, that part is the same program.
When the answer looks wrong, the first thing to check is what the program actually read.
ZeroDivisionError, IndexError or ValueError, depending on what you asked. One if len(...) == 0 guard is the fix.
- 1
Read a list of marks and print how many passed (33 or above) and how many failed.
Hint · Reading loop, then the two-counter loop. Print the list back before the answer.
- 2
Read a list with
eval()and print it with every item doubled.Hint · Either change it in place with the index form, or build a second list — the question decides which.
- 3
Read two lists from the user and print the items they have in common.
Hint · Two
eval()lines, then the nested loop from the searching page. - 4
Read a list of names and print only those starting with a letter the user chooses.
Hint · Two kinds of input again: the names with a loop, the letter with a plain
input(). - 5
Read a list of numbers and report the largest, with a guard for the empty list.
Hint · The champion program under an
else, withif len(numbers) == 0:above it.
Why does the working loop come after the reading loop rather than inside it?
A program reads names with names.append(int(input(...))). What happens?
The user answers 0 to 'How many marks?'. What does total / len(marks) do?