Skip to content
aviral gupta

// B1.4 · ~25 min · Beginner

Lists: store and change a sequence

After this lesson you can keep several values in one list, read and change items by position, add to the end, and tell when two names share one list.

Lesson 4 of 5 in B1 First steps

You will be able to

  • Write lists, and read items and parts with indexes, slices and len()
  • Change a list in place: replace items, append, and assign to slices
  • Use nested lists, and predict what happens when two names refer to the same list
  1. Warm-up · Activity 1 of 7

    Warm-up from lesson B1.3: what does this print?

    word = "Python"
    print(word[-3:])
  2. Predict · Activity 2 of 7

    Predict before you read on: one of the cubes is wrong, and the program fixes it. What does it print?

    cubes = [1, 8, 27, 65, 125]
    cubes[3] = 64
    print(cubes)
  3. Practice · Activity 3 of 7

    Fill in the method that adds "c" at the end of the list.

    letters = ["a", "b"]
    letters.____("c")
    print(letters)
    letters.("c")
  4. Practice · Activity 4 of 7

    What does this print?

    nums = [1, 2, 3, 4, 5]
    print(nums[1:3], nums[-1], len(nums))
  5. Practice · Activity 5 of 7

    x = [["a", "b"], [1, 2, 3]]. Match each expression to its value.

  6. Brain teaser · Activity 6 of 7

    Brain teaser. Only b is changed. What does print(a) show?

    a = [1, 2, 3]
    b = a
    b.append(4)
    print(a)
  7. Apply · Activity 7 of 7

    Mini-task. Start a shopping list: items = ["milk", "bread"]. Add "eggs" at the end, then replace the first item with "oat milk". Print the list and, on a second line, Items: with the number of items.

    Check your work against this list

Build it yourself

Read the worked example, then write the exercises. Your code runs in your browser or on your computer and is never uploaded.

Worked example

A week of temperatures

The program keeps a week of daily temperatures in a list, Monday first. It reads single days and the weekend with indexes and a slice, corrects one reading, adds the next day, and then puts two weeks into a nested list. Change a temperature and run it again.

main.py

# Temperatures for one week, Monday first.
temps = [12, 14, 13, 17, 19, 21, 18]

print("Days:", len(temps))
print("Monday:", temps[0], "Sunday:", temps[-1])
print("Weekend:", temps[5:])

temps[3] = 16  # Thursday's reading was corrected
temps.append(15)  # next Monday
print("Corrected:", temps)

weeks = [temps[:7], [9, 11, 10, 12, 14, 15, 13]]
print("Week 2, Tuesday:", weeks[1][1])

Run it with

python main.py

Output

Days: 7
Monday: 12 Sunday: 18
Weekend: [21, 18]
Corrected: [12, 14, 13, 16, 19, 21, 18, 15]
Week 2, Tuesday: 11
  • temps[5:] is a new list with the last two days: a slice of a list is a list.
  • temps[3] = 16 changes the list in place; the other items stay where they are.
  • append() made the list one longer: it now has 8 items.
  • weeks[1][1]: first the second week, then the second day in it.
Change it and run it

Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.

The first run downloads Python for your browser (up to 6.5 MB) and keeps it cached. Your code stays on your device.

Exercises

Exercise 1 of 2

First, last and middle

scores = [72, 95, 88, 61, 79] holds test scores in the order they were written. Print three lines: First: 72 Last: 79 Middle: [95, 88, 61] Count: 5 The middle is every score except the first and the last. The checks also try other lists.

Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.

The first run downloads Python for your browser (up to 6.5 MB) and keeps it cached. Your code stays on your device.

Hints
  1. Hint 1

    scores[-1] is the last item, however long the list is.

  2. Hint 2

    scores[1:-1] starts at the second item and stops before the last one.

  3. Hint 3

    print("Count:", len(scores))

Show a solution

One way to solve it. Yours can look different and still pass the checks.

scores = [72, 95, 88, 61, 79]

print("First:", scores[0], "Last:", scores[-1])
print("Middle:", scores[1:-1])
print("Count:", len(scores))
Run it on your computer

Install Python 3.14 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.

main.py

scores = [72, 95, 88, 61, 79]

# First: ... Last: ...
# Middle: ...
# Count: ...
print("First:", scores[0], "Last:", scores[4])

test_main.py

import re

from learnrun import run_main


def run_with(**values):
    with open("main.py", encoding="utf-8") as f:
        code = f.read()
    for name, value in values.items():
        code, count = re.subn(rf"^{name} = .*$", f"{name} = {value!r}", code, count=1, flags=re.M)
        assert count == 1, f"main.py needs the line {name} = ... at the top"
    with open("variant.py", "w", encoding="utf-8") as f:
        f.write(code)
    return run_main(path="variant.py").strip()


def test_first_and_last():
    """The first line shows the first and the last score"""
    got = run_with(scores=[72, 95, 88, 61, 79]).splitlines()[:1]
    assert got == ["First: 72 Last: 79"], f"the first line is {got!r}, expected ['First: 72 Last: 79']"


def test_middle_and_count():
    """The middle scores and the count follow"""
    got = run_with(scores=[72, 95, 88, 61, 79]).splitlines()[1:]
    assert got == ["Middle: [95, 88, 61]", "Count: 5"], f"lines 2 and 3 are {got!r}"


def test_other_list():
    """A list of three scores works too"""
    got = run_with(scores=[50, 60, 70]).splitlines()
    assert got == ["First: 50 Last: 70", "Middle: [60]", "Count: 3"], f"for [50, 60, 70] the program printed {got!r}"

On macOS and Linux, type python3 wherever these commands say python, as in the first lesson.

Run the program:

python main.py

Run the checks (needs learnrun.py in the same folder):

python learnrun.py test
Download learnrun.py

Exercise 2 of 2

Update a playlist

songs = ["Intro", "Blue", "Green"] is a playlist. Change it in place: add "Outro" at the end, then replace the second song with "Red". Print the list, then Songs: and the number of songs. For the starting list that gives: ['Intro', 'Red', 'Green', 'Outro'] Songs: 4

Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.

The first run downloads Python for your browser (up to 6.5 MB) and keeps it cached. Your code stays on your device.

Hints
  1. Hint 1

    songs.append("Outro") adds the song at the end of the same list.

  2. Hint 2

    The second song has index 1: songs[1] = "Red".

  3. Hint 3

    Change the list first and print it afterwards, so the output shows both changes.

Show a solution

One way to solve it. Yours can look different and still pass the checks.

songs = ["Intro", "Blue", "Green"]

songs.append("Outro")
songs[1] = "Red"
print(songs)
print("Songs:", len(songs))
Run it on your computer

Install Python 3.14 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.

main.py

songs = ["Intro", "Blue", "Green"]

# 1. Add "Outro" at the end.
# 2. Replace the second song with "Red".
print(songs)
print("Songs:", len(songs))

test_main.py

import re

from learnrun import run_main


def run_with(**values):
    with open("main.py", encoding="utf-8") as f:
        code = f.read()
    for name, value in values.items():
        code, count = re.subn(rf"^{name} = .*$", f"{name} = {value!r}", code, count=1, flags=re.M)
        assert count == 1, f"main.py needs the line {name} = ... at the top"
    with open("variant.py", "w", encoding="utf-8") as f:
        f.write(code)
    return run_main(path="variant.py").strip()


def test_playlist():
    """Outro is added and the second song becomes Red"""
    got = run_with(songs=["Intro", "Blue", "Green"]).splitlines()[:1]
    assert got == ["['Intro', 'Red', 'Green', 'Outro']"], f"the list printed is {got!r}"


def test_count():
    """The count includes the new song"""
    got = run_with(songs=["Intro", "Blue", "Green"]).splitlines()[1:]
    assert got == ["Songs: 4"], f"the second line is {got!r}, expected ['Songs: 4']"


def test_other_playlist():
    """A playlist of two songs works too"""
    got = run_with(songs=["A", "B"]).splitlines()
    assert got == ["['A', 'Red', 'Outro']", "Songs: 3"], f"for ['A', 'B'] the program printed {got!r}"

On macOS and Linux, type python3 wherever these commands say python, as in the first lesson.

Run the program:

python main.py

Run the checks (needs learnrun.py in the same folder):

python learnrun.py test
Download learnrun.py

Common mistakes

An index past the end

items = ["a", "b"]
print(items[2])

What Python prints

IndexError: list index out of range

Why, and the fix

A list of two items has the indexes 0 and 1. Use items[-1] for the last item, or len(items) - 1 as its index. To add a third item, use append(); assigning to items[2] gives the same error.

A method from another language

items = ["a"]
items.push("b")

What Python prints

AttributeError: 'list' object has no attribute 'push'

Why, and the fix

Python lists have no push method. The method that adds an item at the end is append: items.append("b").

Storing what append() returns

items = ["a", "b"]
items = items.append("c")
print(items[0])

What Python prints

TypeError: 'NoneType' object is not subscriptable

Why, and the fix

append() changes the list itself and returns None. Assigning that result to items throws the list away, and items[0] then fails because None has no items. Call it on its own line: items.append("c").

Python in the browser: Pyodide 314.0.7, MPL-2.0. Licence and source

Exit ticket

5 questions, no hints. Score 80% or more to complete the lesson.

Finish every activity above to unlock the exit ticket.

Report a problem

Spotted something wrong or unclear? Say what, and it will be checked and fixed.

#

At least 20 characters.

Only if you want a reply.

Key ideas

Lists hold several values

A list is written as values between square brackets, separated by commas: squares = [1, 4, 9, 16, 25]. The items can have different types, but usually they all have the same. Lists are indexed and sliced exactly like strings: squares[0] is 1, squares[-1] is 25 and squares[1:3] is [4, 9]. len(squares) gives the number of items, and + joins two lists into a new one. A slice is always a new list.

Lists can be changed

Unlike strings, lists are mutable: you can change them after they exist. squares[2] = 10 replaces one item. squares.append(36) adds an item at the end. You can also assign to a slice, which can change the size of the list: letters[1:3] = ["X"] swaps two items for one, letters[1:3] = [] removes them, and letters[:] = [] empties the whole list. append() changes the list and returns None, so write items.append(x), never items = items.append(x).

Nested lists, and one list with two names

A list can hold other lists: grid = [[1, 2], [3, 4]]. grid[1] is the inner list [3, 4], and grid[1][0] is the first item in it, 3. Assignment never copies a list: after b = a, both names refer to the same list, so b.append(4) is seen through a as well. When you need an independent copy, take a slice of the whole list: b = a[:].

Sources

Last reviewed September 29, 2026