Lists

data-structures
beginner
Store, access, slice, update, copy, and loop over ordered mutable collections.
  • Level: Beginner
  • Estimated time: 25–40 minutes
  • You will learn: Store, access, slice, update, copy, and loop over ordered mutable collections.
  • Practice in: Google Colab, Jupyter, or VS Code

Questions

  • What problem does Lists help us solve in a small Python program?
  • What should we predict before running the example?
  • What value, output, or error should we inspect after changing one line?

Objectives

  • Run a complete example for lists in Colab.
  • Explain the example line by line using plain language.
  • Change one part of the code and predict the result before running it.
  • Recognize one common mistake and use the error message as evidence.

Hands-on episode: Lists

A list is an ordered, mutable collection. You can read items by index, add or remove items, loop over them, slice them, and copy them when you need an independent list.

We will learn this by running code, not by memorizing a definition first. Open the Colab notebook from the button above, find this section, and run each cell in order. Keep a small note beside the notebook with three columns: prediction, actual result, and what changed.

Example 1.1

Predict the list after each line, not only at the end.

tasks = ["read", "practice"]
tasks.append("reflect")
tasks[0] = "predict"
first_two = tasks[:2]
print(tasks)
print(first_two)

Run the cell once without editing it. If the result is different from your prediction, leave the prediction visible and write one sentence about the difference. That sentence is more useful than a perfect first guess.

Explain Example 1.1

  • The list begins with two items at indexes 0 and 1.
  • append mutates the existing list by adding one new item at the end.
  • tasks[0] = ... replaces the first item but leaves the other positions alone.
  • tasks[:2] creates a new list containing indexes 0 and 1, stopping before index 2.

Now explain the example out loud or in a Markdown cell. Use short sentences: “this line creates…”, “this name stores…”, “this output appears because…”. If you cannot explain a line yet, run only the lines above it and inspect the values that exist at that moment.

Challenge 1.1

NoteChallenge

Assign alias = tasks and then run alias.append("review"). Both names show the change because they point to the same list. Then try copy = tasks.copy() and compare the behavior.

Show a safe way to approach the challenge
  1. Copy Example 1.1 into a new Colab cell.
  2. Change exactly one value, name, condition, or line.
  3. Write the expected output before running the cell.
  4. Run the cell and compare the actual result with your prediction.
  5. If the result surprises you, undo the change and try a smaller one.

Suggested first move: Assign alias = tasks and then run alias.append("review").

Debugging checkpoint 1.1

WarningDebugging checkpoint

The error IndexError: list index out of range means the position you asked for does not exist. Check len(items) and remember that the last positive index is len(items) - 1. Also remember that scores.sort() changes the list and returns None; use sorted(scores) when you need a new sorted list.

Do not debug by rewriting the whole example. Read the error type or surprising output, inspect the closest value with print(...) or type(...), then change one thing. This is the same routine you will use in larger projects.

Apply it

Build a grade list in Colab. Add one grade, replace one mistaken grade, compute the total with a loop, sort a copy, and write one sentence explaining the difference between the original and the copy.

Finish by adding a Markdown cell that answers: What did this example teach me that I can reuse in a project?

Key points

  • Learn the concept by running a complete, small example first.
  • Predict before execution so your thinking becomes visible.
  • Change one thing at a time so cause and effect stay clear.
  • Treat errors as clues about the exact line or value Python could not handle.

The problem this lesson solves

A single variable can store one value. Real programs often need a group of values: many scores, many names, many tasks, many measurements. A list stores multiple values in one ordered container.

Lists are one of the first data structures worth mastering because they combine several core ideas:

  • order: items have positions;
  • mutability: the list can change;
  • iteration: loops can visit each item;
  • indexing and slicing: code can pick one item or a smaller list.

How lists store ordered items

A list is one object that stores items in order. Names can point to that same list, or to a separate copy.

flowchart LR
  tasks["name<br/>tasks"] --> list["list object<br/>index 0: 'predict'<br/>index 1: 'practice'<br/>index 2: 'reflect'"]
  alias["name<br/>alias"] --> list
  copy["name<br/>copy"] --> copylist["separate list object<br/>index 0: 'predict'<br/>index 1: 'practice'"]
  list --> slice["slice tasks[1:3]<br/>new list with indexes 1 and 2"]

This diagram explains why aliasing can surprise beginners: two names can point to one mutable list object.

1. Creating, reading, and changing lists

A list is written with square brackets. Items are separated by commas.

scores = [10, 8, 9]
names = ["Ada", "Grace", "Katherine"]

A list can hold any type of value, but beginner programs are usually easier to understand when one list contains one kind of thing.

Example 1

Predict the final printed list before running the code.

tasks = ["read", "practice"]
tasks.append("reflect")
tasks[0] = "predict"
print(tasks)

Step-by-step explanation

  1. tasks = ["read", "practice"]
    • Python creates a list with two strings.
    • Index 0 contains "read"; index 1 contains "practice".
  2. tasks.append("reflect")
    • .append(...) adds a new item to the end of the existing list.
    • The list is now ["read", "practice", "reflect"].
  3. tasks[0] = "predict"
    • Index 0 is replaced.
    • The list is now ["predict", "practice", "reflect"].
  4. print(tasks)
    • Python displays the whole list.

Indexes and length

colors = ["red", "green", "blue"]
print(colors[0])      # red
print(colors[2])      # blue
print(len(colors))    # 3

len(colors) is 3, but the last index is 2. This is a common beginner surprise: indexes start at 0, so a list of length 3 has indexes 0, 1, and 2.

Common mistakes

WarningCommon mistake

Mistake: reaching past the end.

colors = ["red", "green", "blue"]
print(colors[3])

This raises IndexError. The last valid index is len(colors) - 1, which is 2 here.

Check your understanding

2. List methods and loops

A method is an action attached to a value. List methods change or inspect a list.

Method Meaning Example
.append(item) add item to the end tasks.append("review")
.remove(item) remove first matching item tasks.remove("read")
.pop() remove and return the last item last = tasks.pop()
.sort() sort the list in place scores.sort()

Example 2

scores = [70, 90, 80]
scores.append(100)
scores.sort()

for score in scores:
    print(score)

Step-by-step explanation

  1. scores = [70, 90, 80] creates a list.
  2. scores.append(100) changes that same list by adding 100 at the end.
  3. scores.sort() changes the list order to [70, 80, 90, 100].
  4. for score in scores: visits each score one at a time.
  5. The indented print(score) runs once per score.

Method return values

Some list methods change the list and return None. This mistake is common:

scores = [70, 90, 80]
sorted_scores = scores.sort()
print(sorted_scores)

This prints None because .sort() changes scores in place. If you want a new sorted list, use sorted(...):

scores = [70, 90, 80]
sorted_scores = sorted(scores)
print(sorted_scores)

Check your understanding

3. Slicing, copying, and aliasing

A slice creates a smaller list from part of another list.

letters = ["a", "b", "c", "d"]
print(letters[1:3])

The result is ["b", "c"]. The start index 1 is included. The stop index 3 is not included.

Why stop is not included

Think of the slice as cutting between items:

indexes:    0     1     2     3
items:    "a"   "b"   "c"   "d"
cut:     |     |     |     |     |
              start       stop

letters[1:3] starts at index 1 and stops before index 3.

Aliasing: two names, one list

original = ["read", "practice"]
alias = original
alias.append("reflect")
print(original)

This prints ["read", "practice", "reflect"]. alias and original are two names for the same list.

If you need a separate list, copy it:

original = ["read", "practice"]
copy = original.copy()
copy.append("reflect")
print(original)
print(copy)

Common mistakes

WarningCommon mistake

Mistake: expecting assignment to copy a list.

alias = original does not copy the list. It adds another name for the same list object. Use .copy() or a slice original[:] for a shallow copy.

Practice

In Colab, create a shopping list and practice one operation at a time:

shopping = ["rice", "beans", "apples"]
shopping.append("tea")
shopping.remove("beans")
print(shopping[:2])

Before each line, predict the exact list.

Check your understanding

Key points

TipKey points
  • Lists store ordered collections of values.
  • Indexes start at 0; the last index is len(items) - 1.
  • Lists are mutable: methods and item assignment can change them.
  • A for loop can process each list item.
  • Slices use start:stop, where stop is not included.
  • Assignment creates an alias, not a copy.

References

  • Python Tutorial: lists: https://docs.python.org/3/tutorial/introduction.html#lists
  • Python Tutorial: more on lists: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
Back to top