Reading a List with a Loop
Every list so far has been typed into the program by you. A real program is given its data by whoever is using it — and input() hands back one string, not a list. The standard way round that is the one on this page: ask how many values there will be, then go round that many times, appending one each round.
1Why this needs a loop
Because you do not know how many values there will be when you write the program — and a program cannot have a different number of input() lines depending on the answer. A loop can run a different number of times on every run, which is exactly the shape of the problem. The count is asked first, so that the loop knows how many rounds to take.
- how many numbers,
n - then
nnumbers, one at a time
- start with an empty list
- cast each value and
append()it
- the finished list, and how many items it holds
2The program
# read a list of numbers, asking how many there will be first
n = int(input('How many numbers? '))
numbers = []
for i in range(n):
value = int(input('Enter number ' + str(i + 1) + ': '))
numbers.append(value)
print('The list is', numbers)
print('It has', len(numbers), 'items')How many numbers? 3 Enter number 1: 10 Enter number 2: 20 Enter number 3: 30 The list is [10, 20, 30] It has 3 items
n = int(input('How many numbers? '))The count, cast to a whole number because range() will not take text. This one question is what turns an unknown number of values into a known number of rounds.
numbers = []An empty list, made BEFORE the loop. It has to exist before anything can be appended to it, and it has to be outside the loop or each round would throw the previous value away.
for i in range(n):n rounds. The loop variable i is not used to index anything here — it is only there to number the prompts, which is the one job it has.
value = int(input('Enter number ' + str(i + 1) + ': '))Three things at once: build the prompt, read the answer, cast it. str(i + 1) is what lets the number be joined to the text — + refuses to mix a string with a number.
numbers.append(value)One item on the end of the list, once per round. After n rounds the list holds n items, which is what len() confirms on the last line.
numbers = [] goes above the loop, always. Put it inside and every round starts with an empty list again, so the finished list holds exactly one item — the last one typed. It is the same fault as total = 0 inside a loop, and it looks just as reasonable.How many numbers? 3 Enter number 1: 10 Enter number 2: 20 Enter number 3: 30 The list is [30] It has 1 items
3Numbering the prompts
'Enter number ' + str(i + 1) + ': ' is worth taking apart, because it is the first time a prompt has been built rather than written out. i counts 0, 1, 2, so i + 1 counts 1, 2, 3 — people number things from one. str() is what makes the join legal:
# text and numbers do not add
i = 0
print('Enter number ' + str(i + 1) + ': ')
print('Enter number', i + 1)Enter number 1: Enter number 1
'Enter number ' + (i + 1) raises TypeError. can only concatenate str (not "int") to str — the same refusal as anywhere else. Inside input() the prompt has to be one finished string, so str() is not optional there. In a print() you can use commas instead and let print() do the joining, which is why the second line above needs no str().4The same shape, for names
Nothing about the shape is about numbers. Drop the int() and the same program reads a list of names — and dropping it is not an oversight, it is the point: a name is text and must stay text.
# the same shape, reading names instead of numbers
n = int(input('How many names? '))
names = []
for i in range(n):
name = input('Enter name ' + str(i + 1) + ': ')
names.append(name)
print('The list is', names)How many names? 2 Enter name 1: Asha Enter name 2: Ravi The list is ['Asha', 'Ravi']
Notice the quotes in the output. print() shows a list the way Python would write it, so the strings keep their quotes — which is how you can tell at a glance that these are text and the numbers in the first program were not.
5What can go wrong
int('ten') raises ValueError: invalid literal for int() with base 10: 'ten' and the program stops there, halfway through filling the list. Nothing on this course fixes that yet — try/except is Class 12 — but you should know why it happens.
Type 5 and then get bored after three: the program keeps asking, because the loop was told 5 rounds. The count is a promise the user has to keep.
range(0) runs no rounds at all, so the list stays empty and prints as []. No error — and any program that then does numbers[0] or divides by len(numbers) will fail on it.
6Recap
It is what turns an unknown number of values into a known number of rounds — and it is why this is a for loop and not a while.
numbers = [] inside the loop leaves you with a one-item list holding whatever was typed last.
int() for numbers, nothing at all for text. Each value is read and cast on its own, one round at a time.
A prompt is one finished string, so a number joined into it must be converted. print() takes commas instead and needs no str().
- 1
Read a list of marks and print the total and the average.
Hint · This program, then the total program from two pages back. Nothing new is needed.
- 2
Read a list of numbers and print the largest, without
max().Hint · The champion starts at
numbers[0]— which exists only after the reading loop has finished. - 3
Read
nnumbers and build two lists as you go: the evens and the odds.Hint · Three empty lists above the loop, and the
ifinside the reading loop rather than in a second one. - 4
Read a list of names and print them numbered, one per line.
Hint · Read with one loop, print with another — over
range(len(names)), so you have the number. - 5
Read numbers until the user types
-1, without asking the count first.Hint · A
whileloop and a sentinel — the count is unknown, soforis the wrong tool.
Where must numbers = [] be written?
Why does the prompt need str(i + 1) rather than just i + 1?
The user answers 0 to 'How many numbers?'. What happens?