KS41CP2 6.2 30 min read 10 question quiz 16 exam marks

Lists, Strings and Files in Python

One dimensional and two dimensional lists, every string operation Paper 2 expects, and reading and writing text files, with the off by one traps that break more programs than anything else.

Lists

A list holds many values under one name, each found by its index, counted from 0.

Python
scores = [14, 9, 21, 6, 18]
print(scores[0])
print(scores[-1])
scores[3] = 11
print(len(scores))

scores[0] is 14 and scores[-1] is the last item. len(scores) is 5, and the last index is 4.

len gives the count, not the last index

A five item list has len 5 and a highest index of 4. Looping to len(scores) runs one step too far and raises an IndexError.

Working through a list

Python
total = 0
for score in scores:
    total = total + score
print("Average:", total / len(scores))

Loop over the items when you only need the values. Loop over range(len(scores)) when you need the index as well, for example to change items in place.

Useful list operations

Python
scores.append(25)
scores.insert(0, 3)
scores.remove(9)
value = scores.pop()
scores.sort()
print(max(scores), min(scores), sum(scores))

Two dimensional lists

A list of lists, useful for anything grid shaped.

Python
board = [[1, 0, 0],
         [0, 1, 0],
         [0, 0, 1]]

print(board[1][2])

for row in board:
    for cell in row:
        print(cell, end=" ")
    print()

The first index selects the row, the second the position within it.

An array compared with a linked listTwo data structures compared. An array holds Ada, Bob, Cai, Dee and Eve in one continuous block of memory at addresses 400, 404, 408, 412 and 416, indexed 0 to 4. Because the items are evenly spaced the computer can jump straight to any index by calculating start address plus index times item size, but inserting an item in the middle means shifting every item after it, and the array cannot grow beyond its declared size. A linked list holds the same names in nodes scattered anywhere in memory. Ada sits at address 512 and its next pointer holds 730, where Bob sits. Bob's pointer holds 604 for Cai. Cai's pointer holds 918 for Dee. Dee's pointer holds null, marking the end. Reaching the fourth item means following three pointers from the head, but inserting in the middle only changes two pointers and the list can grow as long as there is free memory.ARRAYone block of memory, fixed sizeAdaindex 0address 400Bobindex 1address 404Caiindex 2address 408Deeindex 3address 412Eveindex 4address 416To reach index 3 the computer works out 400 + 3 x 4 and jumps straight there.Inserting in the middle means shifting every item after it along by one.LINKED LISTscattered nodes, each holding a pointer to the nextAdaat 512next730Bobat 730next604Caiat 604next918Deeat 918nextnullTo reach the fourth item you must start at the head and follow three pointers.Inserting in the middle changes two pointers, and the list can grow at any time.
Arrays win on reading a known position. Linked lists win on inserting and deleting, and on not needing to know the size in advance.
A list is a row of numbered lockersA list drawn as a row of numbered lockers, with the code that changes it. The list scores starts with five values, 72, 85, 90, 64 and 78, in lockers numbered from 0. The call append of 88 adds a new locker on the end, so the list now has six items. The assignment scores, bracket, 1, bracket, equals 99 replaces what was in locker 1, the 85, with 99. Reading scores bracket 2 opens locker 2 and finds 90, and len of scores is 6, so the last index is 5, one less than the length. The program prints 90 and 6.lists.py1scores = [72, 85, 90, 64, 78]2scores.append(88)3scores[1] = 994print(scores[2], len(scores))output90 6the item at index 2, then the length720991902643784885appendchangedscores[2]len(scores) is 6, so the last index is 51234
  1. The list holds its items in order, and the first locker is number 0.
  2. append() puts a new item on the end, so the list grows.
  3. Assign to an index to replace what is there. The old value is gone.
  4. scores[2] opens locker 2. len(scores) counts the lockers, so the last index is one less.
Index from 0, and remember the last index is len minus 1.

Strings

A string is a sequence of characters, indexed from 0 just like a list.

Python
word = "Computing"
print(len(word))
print(word[0])
print(word[0:3])
print(word[-1])
print(word.upper())
print(word.lower())
print(word.find("put"))
print(word.replace("ing", "er"))
print("put" in word)

word[0:3] is a slice, and it gives characters 0, 1 and 2. Like range, a slice stops before the second number.

Splitting and joining

Python
line = "Amira,15,Year 10"
parts = line.split(",")
print(parts[0])
joined = "-".join(parts)

split is how you take a line read from a file apart, and it is needed in almost every Paper 2 task that involves a data file.

Characters as numbers

Python
print(ord("A"))
print(chr(66))

ord gives the character set code and chr converts back, which is how case conversion and simple ciphers are done.

A string is a row of characters, each with an indexThe word Computer drawn as eight letter tiles. Above each tile is its index, counting from 0 at the first letter to 7 at the last, and below it is the negative index, counting back from the end, from minus 8 to minus 1. A slice takes part of the string: word, bracket, 0, colon, 3 gives Com, which runs from index 0 up to but not including index 3, and word, bracket, 3, colon gives puter, from index 3 to the end. word minus one is the last character, r. Below, four things you can do with a string: len gives the number of characters, which is 8; upper gives a new string in capitals; find gives the index of the first match, here 3 for the letter p; and a plus sign joins two strings together. A string is never changed in place: each of these gives back a new string.indexfrom the endC0-8o1-7m2-6p3-5u4-4t5-3e6-2r7-1word[0:3] = "Com"word[3:] = "puter"word[-1] = "r"123len(word)8how many charactersword.upper()"COMPUTER"a new string in capitalsword.find("p")3index of the first matchword + "s""Computers"+ joins two strings4
  1. Every character has an index. The first is 0, and negative indexes count back from the end.
  2. A slice [a:b] runs from index a up to, but not including, b. Leave b out to go to the end.
  3. [-1] is the last character.
  4. Functions and methods build and search strings, and each one gives back a new string.
In exam pseudocode the same idea is written as substring: check your board's command set for the exact form.
Six string methods applied to the text with spaces round Hello World, and why the original never changesSix string methods applied to text equal to two spaces, Hello World, two spaces. upper gives all capitals. strip removes the spaces at the ends, giving Hello World. replace of l with capital L swaps every match, giving HeLLo WorLd with its spaces. strip then split on a space breaks the text into the list Hello, World. join of the list a, b, c with a hyphen builds the text a-b-c. find of World gives 8, the position where it starts. On the right a reminder that strings do not change: text dot upper makes a brand new string and leaves text as it was, so to keep the result you assign it, name equals name dot upper. Split and join are opposites.text = "  Hello World  "1text.upper()"  HELLO WORLD  "2text.strip()"Hello World"3text.replace("l", "L")"  HeLLo WorLd  "4text.strip().split(" ")["Hello", "World"]5"-".join(["a", "b", "c"])"a-b-c"6text.find("World")8Strings are fixed7textstays the sametext.upper() makesa brand new stringnew stringkeep it by assigning:name = name.upper()split and join are opposites: split breaks text into a list, join builds text from a list.
  1. upper() makes every letter a capital.
  2. strip() removes spaces from both ends.
  3. replace() swaps every match for something else.
  4. split() breaks a string into a list.
  5. join() builds a string from a list.
  6. find() gives the position of the first match, or -1 if there is none.
  7. A method returns a new string. The original is never changed unless you assign the result.
Methods return new strings. To keep the result, assign it to a variable.

Files

A program that forgets everything when it closes is of limited use. Writing to a file makes data persist between runs.

Reading

Python
file = open("scores.txt", "r")
for line in file:
    print(line.strip())
file.close()

strip() removes the newline character at the end of each line, and forgetting it is why comparisons against read values so often fail.

The safer form closes the file for you even if something goes wrong:

Python
with open("scores.txt", "r") as file:
    lines = file.readlines()

Writing

Python
with open("scores.txt", "w") as file:
    file.write("Amira,18\n")
    file.write("Ben,14\n")
"w" destroys the existing file

Opening in write mode empties the file before you write anything. Use "a" to append to the end and keep what is already there. Losing a data file this way in a Paper 2 task costs a great deal of time.

Putting it together

Python
totals = {}
with open("scores.txt", "r") as file:
    for line in file:
        parts = line.strip().split(",")
        name = parts[0]
        score = int(parts[1])
        totals[name] = score

for name in totals:
    print(name, totals[name])

Note the int() on the score. Everything read from a text file is a string, every time.

Reading, writing and appending to a text fileThree ways to open a text file, one card each. Opening with mode r reads the file: the program looks at the lines, nothing in the file changes, and it is an error if the file does not exist. Opening with mode w writes: it creates the file if it is missing, but if it exists everything in it is erased first, so a file that held two lines ends up holding only the new line. Opening with mode a appends: the new line is added to the end and the old lines are kept. The code below uses the with statement, which closes the file automatically, and writes the line Tia comma 51 followed by a newline character. Always close a file, because unwritten data may stay in a buffer and never reach the disk."r" readbeforeAsha,42Tom,37"w" writebeforeAsha,42Tom,37"a" appendbeforeAsha,42Tom,37programreads each linethe file is not changederror if it does not existTia,51erases what was therecreates the file if missingAsha,42Tom,37Tia,51adds to the endkeeps what was theresave.py1with open("scores.txt", "a") as f:2    f.write("Tia,51\n")with closes the file for you\n starts a new linea is safer than w for addingalways close a file, or the last lines may never reach the disk1234
  1. r reads. The file is only looked at, and it must already exist.
  2. w writes. Everything already in the file is erased first.
  3. a appends. New lines go on the end and the old ones are kept.
  4. with closes the file for you, and \n ends a line.
If you mean to add to a file, open it with a. Opening it with w by mistake wipes it.

Key terms you must be able to define

List
A Python data structure holding many values under one name, accessed by index.
Index
The position of an item, counted from zero.
Two dimensional list
A list whose items are themselves lists, used for grids and tables.
Slice
A section of a list or string taken between two indexes, stopping before the second.
split
A string method that divides a string into a list at a given separator.
strip
A string method that removes whitespace, including the newline, from both ends.
append
A list method that adds an item to the end.
Append mode
Opening a file with "a" so that new data is added to the end rather than replacing it.

Flashcards

Say the definition out loud before you flip the card. Retrieving it from memory is what builds recall, reading it again is not.

DefineList
AnswerA Python data structure holding many values under one name, accessed by index.
DefineIndex
AnswerThe position of an item, counted from zero.
DefineTwo dimensional list
AnswerA list whose items are themselves lists, used for grids and tables.
DefineSlice
AnswerA section of a list or string taken between two indexes, stopping before the second.
Definesplit
AnswerA string method that divides a string into a list at a given separator.
Definestrip
AnswerA string method that removes whitespace, including the newline, from both ends.
Defineappend
AnswerA list method that adds an item to the end.
DefineAppend mode
AnswerOpening a file with "a" so that new data is added to the end rather than replacing it.

Reach the top grade on this topic

Paper 2 tasks are almost always list or file tasks, so the details here are worth more than anywhere else.

Strip and cast every line you read. int(line.strip()) handles both the newline and the type in one step, and skipping either produces a fault that is hard to see because the value looks correct when printed.

Use len(list) - 1 when you need the last index. Write it deliberately rather than by habit, and check it against a small example.

Choose the loop that matches what you need. for item in list when you only need values, for i in range(len(list)) when you need to change items in place.

Open files in the right mode. Reading is "r", appending is "a", and "w" empties the file first. Say why you chose the mode if a question asks.

Mistakes that cost marks here

Avoid these
  • Looping to len(list) rather than len(list) - 1 when using range with an index.
  • Forgetting strip(), so a value read from a file carries a newline and never matches.
  • Forgetting to cast a value read from a file before doing arithmetic with it.
  • Opening a file in "w" mode when you meant to add to it, which deletes the existing contents.
  • Expecting a slice like word[0:3] to include index 3. It stops before it.
Fun fact

Python counts from zero because an index is really an offset from the start of the data. The first item sits zero places along, which is also why a slice like [0:3] gives three items and stops before index 3.

Knowledge check

0 of 10 answered
1A list called names holds 8 items. What is the index of the last one?
2What does scores[-1] return?
3What does 'Computing'[0:3] give?
4What does 'Amira,15'.split(',') return?
5Why is strip() usually needed on a line read from a text file?
6What happens if a file is opened with mode 'w' when it already exists?
7In a two dimensional list called grid, what does grid[2][0] refer to?
8Which method adds an item to the end of a list?
9Why must a number read from a text file be converted before it is used in a calculation?
10What does ord('A') return, given that 'A' has the code 65?
Score 0 / 10

Exam-style questions

Five written questions in the style of the real paper. Write a full answer, then let the marker check it against the mark scheme.

16 marks
1A list called marks holds 30 integers. Write a Python program that outputs the highest mark.4 marks
Write

Mark scheme0 / 4
  • LSets an initial highest value from the list, such as marks[0]
  • LLoops through the list
  • LCompares each item with the current highest
  • LUpdates the highest and outputs it after the loop
Model answer

A correct program is: highest = marks[0], then for mark in marks: if mark > highest: highest = mark, then print("The highest mark is", highest). Starting from marks[0] rather than from zero matters, because a list containing only negative values would otherwise report zero as the highest. The print statement must be outside the loop, otherwise it outputs a running maximum on every pass rather than the final answer. Python's built in max(marks) would also be accepted.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
2Explain why a program that reads a name from a file and compares it with a name typed by the user might never find a match, even when the names look identical.3 marks
Explain

Mark scheme0 / 3
  • LA line read from a file includes the newline character at the end
  • LThe typed name does not include that character, so the two strings differ
  • LUsing strip() removes it so the comparison works
Model answer

When a line is read from a text file it includes the newline character that ended the line in the file. The name typed by the user does not include that character, so although the two look identical when printed, one is a character longer than the other and the comparison is False. The fix is to remove the whitespace at the ends of the line read from the file, using name = line.strip(), after which the two strings genuinely are equal and the comparison succeeds. The same problem causes numbers read from files to fail if they are compared before being cast.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
3A text file called results.txt has one record per line in the form name,score. Write a Python program that reads the file and outputs the name of every student who scored more than 50.5 marks
Write

Mark scheme0 / 5
  • LOpens the file for reading
  • LLoops through each line of the file
  • LSplits each line on the comma
  • LCasts the score to an integer
  • LCompares with 50 and outputs the name for those above it
Model answer

A correct program is: with open("results.txt", "r") as file: then for line in file: then parts = line.strip().split(",") then name = parts[0] then score = int(parts[1]) then if score > 50: print(name). Three details carry the marks. The line must be stripped before splitting, or the score picks up a trailing newline. The score must be cast with int(), because everything read from a text file is a string and comparing a string with 50 would fail. Using with open means the file is closed automatically even if an error occurs part way through.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
4Explain the difference between opening a file in write mode and in append mode, and give one situation where each is appropriate.4 marks
Explain

Mark scheme0 / 4
  • LWrite mode empties the existing file before writing
  • LAppend mode adds new data to the end, keeping what is there
  • LGives a suitable use of write mode, such as creating a fresh report
  • LGives a suitable use of append mode, such as adding to a log of results
Model answer

Opening a file in write mode, using "w", deletes everything already in the file before a single character is written, so the file always ends up containing only what this run of the program put there. Append mode, using "a", leaves the existing contents alone and adds the new data to the end. Write mode is appropriate when the file is being regenerated in full each time, for example a report that should reflect only the current data. Append mode is appropriate when each run adds to a growing record, for example a log file that records the result of every game played, where opening in write mode would destroy the entire history every time the program ran.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
Machine mark 0 / 16