Grade by Grade
A. Programming Concepts and Skills · Arrays and Subprograms

Declaring, Initializing, Accessing and Modifying Lists

A1.6 A1.5 A4.1About 70 minutes
Learning goals
  • I can declare and initialize a list in several ways, including from user input.
  • I can access and change an element by its index.
  • I can add and remove elements with append, insert, pop, remove and del, and predict how the other elements shift.
  • I can explain the difference between two names for one list (an alias) and a true copy.

Words to know

declare
To introduce a variable (here, an array) to the program. In Python, a list is declared the first time you assign it, e.g. marks = [].
initialize
To give an array its starting values, e.g. counts = [0] * 6.
method
A subprogram that belongs to a value and is called with a dot, e.g. marks.append(87).
append
To add an element to the end of a list: a.append(x).
mutable
Able to be changed after it is created. Lists are mutable; strings and numbers are not.
alias
A second name for the same list. Changing the list through one name is visible through the other.
ValueError
The run-time error Python raises when a value is the right type but not acceptable, e.g. removing an element that is not in the list.

A sign-up sheet that changes

Your school is running a Winter Carnival snowshoe race. Students sign up all week. Some add their names, a few drop out, and the organizer fixes a misspelled name. A list that only sits there is not much use: real programs create lists, read them, and change them. The curriculum calls this declaring, initializing, modifying and accessing an array. This lesson shows you each one in Python.

Declaring and initializing

In languages like Java you declare an array with its type and size before you use it, e.g. int[] counts = new int[6];. Python is simpler: a list is declared the moment you assign it. The starting values you give it are its initialization. Here are four common ways:

names = [] # empty list, to be filled later
marks = [78, 91, 66, 85] # literal values
counts = [0] * 6 # six zeros
years = list(range(2020, 2025)) # 2020 to 2024
print(names, marks, counts, years)

Output: [] [78, 91, 66, 85] [0, 0, 0, 0, 0, 0] [2020, 2021, 2022, 2023, 2024]. [0] * 6 repeats the list [0] six times. Use it when you know the size but not the values yet.

Accessing and modifying one element

You already know that marks[1] reads the element at index 1. Put the same thing on the left of = and you change that element. This is allowed because lists are mutable.

marks = [78, 91, 66, 85]
marks[2] = 70 # replace 66 with 70
marks[0] = marks[0] + 5 # add 5 to the first mark
print(marks)

Output: [83, 91, 70, 85]. The length does not change; two elements were replaced.

You can only change elements that already exist. marks[4] = 60 on a list of length 4 raises IndexError: list assignment index out of range. To make a list longer, use the methods below.

Adding and removing elements

A method is a subprogram that belongs to a value. You call it with a dot: list_name.method(...).

  • a.append(x) adds x to the end.
  • a.insert(i, x) puts x at index i; everything from i onward shifts one place right.
  • a.pop() removes the last element and gives it back (returns it). a.pop(i) removes and returns the element at index i; everything after it shifts left.
  • a.remove(x) removes the first element equal to x. If x is not there: ValueError.
  • del a[i] deletes the element at index i (nothing is returned).
  • x in a is True if x is an element of a. Use it before remove to avoid the ValueError.
before:Ava0Ben1Dev2Eli3insert(2, "Cy"):Ava0Ben1Cy2Dev3Eli4pop(0):Ben0Cy1Dev2Eli3→ "Ava" is returned
insert(2, "Cy") puts "Cy" at index 2 and shifts "Dev" and "Eli" (blue) one place to the right. Then pop(0) removes "Ava" and every other element shifts one place left, so all the indexes change.
Worked example

Example 1: Trace the sign-up list

Predict what this prints, keeping track of the list after every line.

sign_up = ["Ava", "Ben", "Dev"]

sign_up.append("Eli")

sign_up.insert(2, "Cy")

first = sign_up.pop(0)

sign_up.remove("Dev")

sign_up[0] = "Bea"

print(first, sign_up, len(sign_up))

  1. Line 1: ["Ava", "Ben", "Dev"]
  2. Line 2, append: ["Ava", "Ben", "Dev", "Eli"]
  3. Line 3, insert at index 2: ["Ava", "Ben", "Cy", "Dev", "Eli"]
  4. Line 4, pop(0) removes and returns "Ava", so first is "Ava": ["Ben", "Cy", "Dev", "Eli"]
  5. Line 5, remove("Dev"): ["Ben", "Cy", "Eli"]
  6. Line 6, replace index 0: ["Bea", "Cy", "Eli"]. The length is 3.

Ava ['Bea', 'Cy', 'Eli'] 3

Filling a list from user input

Most lists are built while the program runs. The pattern is: start with an empty list, loop, and append each new value. Remember from Programming Basics that input() always returns a string, so convert it with int() or float() first.

snowfall = []
for day in range(1, 4):
cm = float(input("Snowfall on day " + str(day) + " (cm): "))
snowfall.append(cm)
print("You entered:", snowfall)

A sample run where the user types 4.5, 0 and 12: the program shows three prompts and then You entered: [4.5, 0.0, 12.0].

Another common way is to read all the values on one line and split them. input().split() breaks the line at the spaces and gives a list of strings. A loop then converts each one:

words = input("Enter marks separated by spaces: ").split()
marks = []
for w in words:
marks.append(int(w))
print(words)
print(marks)

If the user types 78 91 66, the program prints ['78', '91', '66'] (strings, in quotes) and then [78, 91, 66] (integers).

Two names for one list: aliasing

Here is a surprise that catches many programmers. When you write b = a for a list, Python does not copy the list. It makes b a second name, an alias, for the same list. Change the list through b and you will see the change through a too. To get an independent copy, use a.copy() (or list(a), or the slice a[:]).

b = a (alias)c = a.copy() (copy)ab592one list, two namesac592592two separate lists
Left: b = a makes two names point to one list, so b[0] = 0 would also change a[0]. Right: a.copy() builds a second list with the same values, so changing c leaves a alone.
a = [5, 9, 2]
b = a
c = a.copy()
b[0] = 0
c[1] = 100
print(a)
print(b)
print(c)

Output: [0, 9, 2], [0, 9, 2], [5, 100, 2]. Changing b also changed a (same list). Changing c did not (separate copy).

Worked example

Example 2: Fix the run-time errors

Each line below crashes. Name the error and fix it.

(a) teams = ["Leafs", "Jets"] then teams[2] = "Oilers"

(b) teams = ["Leafs", "Jets"] then teams.remove("Canucks")

(c) scores = [] then print(scores.pop())

  1. (a) IndexError: list assignment index out of range. Index 2 does not exist yet; you can only assign to existing indexes. Fix: teams.append("Oilers").
  2. (b) ValueError: list.remove(x): x not in list. Fix: check first, if "Canucks" in teams: teams.remove("Canucks").
  3. (c) IndexError: pop from empty list. There is nothing to remove. Fix: check first, if len(scores) > 0: print(scores.pop()).

Use append to grow a list, and check with in or len() before removing.

Just for fun

A list walks into a café and asks for a coffee. The barista says, "Sorry, we're all out."

The list says, "No problem, I'll just .pop() next door."

Hands-on activity

Shuffle the line-up

You need: 6 to 8 index cards or paper slips, a pen, and a computer with Python.

  1. Write a different name of a Canadian city on each card and lay 5 of them in a row on a table. Put a small index-number card under each position (0, 1, 2, ...).
  2. Ask a family member to read out instructions from this list one at a time, while you move the cards: append("Iqaluit"), insert(1, "Halifax"), pop(0), remove("Regina") (if you have it), pop(). After each move, update the index cards so they still start at 0.
  3. Write your predicted final list on paper. Then type the same starting list and instructions into Python and print the list after each step. Did your table match Python every time?

What to look for: when a card is inserted or removed in the middle, the student notices that the index of every card after it changes.

Your turn

1

Write one line that creates a list called zeros holding ten 0s.

2

marks = [70, 82, 95]. Write a line that changes 82 to 85.

3

Predict the output:

a = [1, 2, 3]

a.append(4)

a.insert(0, 9)

print(a)

4

Predict the output:

a = [10, 20, 30, 40]

x = a.pop(1)

print(x, a)

5

What is the difference between a.pop(2) and a.remove(2)?

6

Why does marks[3] = 77 crash when marks = [70, 82, 95]? How do you add 77 at the end?

7

Predict the output:

x = [1, 2]

y = x

y.append(3)

print(len(x))

More practice: warm-up

1

Which method adds an element to the end of a list?

2

What does [7] * 3 make?

3

What does list(range(4)) make?

4

What type of value does input() give back?

5

What does 3 in [1, 2, 3] give?

More practice: on your own

1

Predict the output:

t = [-5, -9, 2]

t[1] = t[0] + t[2]

t.append(t[1] * 2)

print(t)

2

Predict the output:

a = ["a", "b", "c", "d"]

del a[1]

a.insert(1, "z")

print(a)

3

Write a program that asks how many maple trees a student measured, then reads that many heights in metres (one per line) into a list and prints the list.

4

Predict the output:

a = [3, 1, 3, 1]

a.remove(1)

print(a)

5

Give three different ways to make an independent copy b of a list a.

Challenge

1

Predict the output and explain:

a = [1, 2, 3]

b = a

b = b + [4]

print(a, b)

2

A list q holds a line of customers at a skating rink rental desk. Write code that serves (removes and prints) the first customer, then adds "Noor" at the end. Why is pop(0) slower than pop() on a very long list?

3

Predict the output:

a = [0] * 3

for i in range(3):

    a[i] = i * i

a.insert(1, a[-1])

print(a)

Check your understanding

Quiz

1.

Which line creates a list of five zeros?

2.

a = [4, 8, 12]. After a.insert(0, 2), what is a[1]?

3.

What does a.pop() do?

4.

a = [1, 2, 3]. Which line raises a run-time error?

5.

After x = [1, 2] and y = x and y[0] = 9, what is x?

6.

A user types 5 10 15. What is input().split()?

For parents and teachers

Big idea: Expectation A1.6 asks students to write programs that declare, initialize, modify and access one-dimensional arrays. This lesson covers each of those in Python, plus the run-time errors (A4.1) that come from misusing them.

How to help: The card activity is worth doing for real; moving physical cards makes "everything shifts" obvious. Afterwards, call out a short sequence of list operations and ask your teen to predict the result before running it.

Common difficulties:

  • Confusing pop(i) (by index) with remove(x) (by value).
  • Trying to grow a list with a[len(a)] = x. Python requires append or insert.
  • Forgetting that input() gives strings, so ["78", "91"] is not a list of numbers.
  • Aliasing. If two variables seem to change together, check for a b = a line. Use .copy() when an independent list is wanted.