We use cookies to enhance your experience on the site
CodeWorlds

Lists as Expedition Trails

Welcome back to the trail, @name! Darwin here with the next stage of our expedition.

In the previous module you learned the basics - variables, data types, functions. Now it's time for something more powerful - data collections. On a real expedition you need to manage many elements at once: a list of places to visit, a catalog of discovered species, equipment supplies. In Python we use lists for this.

What Are Lists?

A list is an ordered collection of elements that can be of different types. Think of it as an expedition trail - a sequence of points that you visit one after another.

1# Expedition trail through the jungle
2expedition_route = ["Base Camp", "River", "Waterfall", "Mountain Peak"]
3
4# Discovered species (order matters - chronology of discoveries!)
5discovered_species = ["Python regius", "Panthera leo", "Loxodonta africana"]
6
7# Temperatures from the last week
8daily_temperatures = [32, 31, 35, 33, 34, 32, 31]
9
10# A list can contain different types
11expedition_data = ["Day 1", 15.5, True, ["Note 1", "Note 2"]]

Key characteristics of lists:

  • Ordered - order matters
  • Mutable - they can be modified
  • Can contain duplicates
  • Can contain different data types
  • Indexed from 0

Creating Lists

1# Empty list - like a clean expedition journal
2empty_path = []
3empty_species = list()
4
5# List with elements
6jungle_animals = ["Tiger", "Elephant", "Monkey", "Parrot"]
7
8# List of numbers
9distances_km = [5, 10, 15, 20, 25]
10
11# List from range()
12numbers = list(range(1, 11))  # [1, 2, 3, ..., 10]
13even_numbers = list(range(0, 21, 2))  # [0, 2, 4, ..., 20]
14
15# Nested lists (list of lists)
16expedition_teams = [
17    ["Darwin", "Alex", "Maya"],
18    ["Sarah", "Tom", "Lisa"],
19    ["Chen", "Ahmed", "Sofia"]
20]

Accessing Elements - Indexing

In the jungle every place has its position on the map. In Python we use indexes (from 0!).

1animals = ["Tiger", "Elephant", "Monkey", "Parrot", "Python"]
2
3# Indexing from the beginning (0, 1, 2...)
4first_animal = animals[0]   # "Tiger"
5second_animal = animals[1]  # "Elephant"
6third_animal = animals[2]   # "Monkey"
7
8# Indexing from the end (-1, -2, -3...)
9last_animal = animals[-1]   # "Python"
10second_last = animals[-2]   # "Parrot"
11
12# Index out of range - error!
13# wrong = animals[10]  # IndexError!
14
15print(f"First discovered species: {first_animal}")
16print(f"Last discovered species: {last_animal}")

Remember: Python indexes from 0, so the first element has index [0], not [1]!

Slicing - Extracting Fragments

Sometimes you only need a portion of the trail. In Python we use slicing:

1route = ["Start", "Point A", "Point B", "Point C", "Point D", "Finish"]
2
3# Slicing: list[start:stop:step]
4first_three = route[0:3]     # ["Start", "Point A", "Point B"]
5middle = route[2:5]          # ["Point B", "Point C", "Point D"]
6last_two = route[-2:]        # ["Point D", "Finish"]
7all_but_first = route[1:]    # From second to end
8all_but_last = route[:-1]    # From beginning to second-to-last
9
10# Every other element
11every_second = route[::2]    # ["Start", "Point B", "Point D"]
12
13# Reverse the list!
14reversed_route = route[::-1] # ["Finish", "Point D", ..., "Start"]
15
16print(f"First 3 points: {first_three}")
17print(f"Reversed route: {reversed_route}")

Slicing syntax: `list[start:stop:step]`

  • `start` - from which index (inclusive)
  • `stop` - up to which index (NOT inclusive!)
  • `step` - step size (default 1)

Modifying Lists

Unlike strings, lists are mutable - you can change them!

1discovered = ["Tiger", "Elephant", "Monkey"]
2
3# Changing a single element
4discovered[1] = "Rhino"  # Replacing elephant
5print(discovered)  # ["Tiger", "Rhino", "Monkey"]
6
7# Changing a fragment via slicing
8discovered[1:3] = ["Lion", "Cheetah", "Hyena"]
9print(discovered)  # ["Tiger", "Lion", "Cheetah", "Hyena"]
10
11# Deleting an element by index
12del discovered[0]
13print(discovered)  # ["Lion", "Cheetah", "Hyena"]

List Methods - Exploration Tools

Python offers many methods for working with lists. Here are the most important ones:

append() - add to end

1species = ["Tiger", "Elephant"]
2species.append("Python")
3species.append("Parrot")
4print(species)  # ["Tiger", "Elephant", "Python", "Parrot"]
5
6# Analogy: Adding a new discovery to the journal

extend() - extend the list

1team1 = ["Darwin", "Alex"]
2team2 = ["Maya", "Sarah"]
3
4team1.extend(team2)  # Adds all elements from team2
5print(team1)  # ["Darwin", "Alex", "Maya", "Sarah"]
6
7# Note the difference:
8# append adds the ENTIRE list as one element
9# extend adds EACH element from the list

insert() - insert at a specific position

1route = ["Start", "Waterfall", "Finish"]
2route.insert(1, "River")  # Insert "River" at position 1
3print(route)  # ["Start", "River", "Waterfall", "Finish"]

remove() - remove a value

1animals = ["Tiger", "Elephant", "Tiger", "Monkey"]
2animals.remove("Tiger")  # Removes the FIRST occurrence
3print(animals)  # ["Elephant", "Tiger", "Monkey"]
4
5# WARNING: ValueError if the element doesn't exist!

pop() - remove and return an element

1supplies = ["Tent", "Binoculars", "Map", "Compass"]
2
3# Pop without argument - removes the last
4last_item = supplies.pop()
5print(last_item)  # "Compass"
6print(supplies)   # ["Tent", "Binoculars", "Map"]
7
8# Pop with index
9first_item = supplies.pop(0)
10print(first_item)  # "Tent"
11print(supplies)    # ["Binoculars", "Map"]

index() - find an element's position

1animals = ["Tiger", "Elephant", "Monkey", "Parrot"]
2position = animals.index("Monkey")
3print(position)  # 2
4
5# ValueError if not found!
6# pos = animals.index("Lion")  # ValueError

count() - count occurrences

1temperatures = [30, 32, 30, 35, 30, 33]
2hot_days = temperatures.count(30)
3print(f"Days with temperature 30°C: {hot_days}")  # 3

sort() - sort (modifies the original list!)

1distances = [15, 5, 25, 10, 20]
2distances.sort()  # Sorts ascending
3print(distances)  # [5, 10, 15, 20, 25]
4
5distances.sort(reverse=True)  # Descending
6print(distances)  # [25, 20, 15, 10, 5]
7
8# Sorting strings (alphabetically)
9animals = ["Zebra", "Antelope", "Lion"]
10animals.sort()
11print(animals)  # ["Antelope", "Lion", "Zebra"]

sorted() - return a sorted copy (does NOT modify the original!)

1distances = [15, 5, 25, 10, 20]
2sorted_distances = sorted(distances)
3print(distances)         # [15, 5, 25, 10, 20] - unchanged!
4print(sorted_distances)  # [5, 10, 15, 20, 25] - new list

Important: `.sort()` modifies the list, `sorted()` returns a new one!

reverse() - reverse the list

1route = ["Start", "A", "B", "Finish"]
2route.reverse()
3print(route)  # ["Finish", "B", "A", "Start"]

clear() - clear the entire list

1old_data = [1, 2, 3, 4, 5]
2old_data.clear()
3print(old_data)  # []

Operations on Lists

1# Concatenation (joining)
2team1 = ["Darwin", "Alex"]
3team2 = ["Maya", "Tom"]
4full_team = team1 + team2  # ["Darwin", "Alex", "Maya", "Tom"]
5
6# Repetition
7supplies = ["Water"] * 3  # ["Water", "Water", "Water"]
8
9# Checking membership (in, not in)
10animals = ["Tiger", "Elephant", "Monkey"]
11print("Tiger" in animals)     # True
12print("Lion" in animals)       # False
13print("Python" not in animals) # True
14
15# Length
16num_animals = len(animals)  # 3
17
18# Min, Max, Sum (for numbers)
19distances = [5, 10, 15, 20]
20print(min(distances))  # 5
21print(max(distances))  # 20
22print(sum(distances))  # 50

Iterating Through Lists

1# For loop - the most popular way
2animals = ["Tiger", "Elephant", "Monkey"]
3
4for animal in animals:
5    print(f"Discovered: {animal}")
6
7# With index - enumerate()
8for index, animal in enumerate(animals):
9    print(f"{index + 1}. {animal}")
10
11# With index starting from 1
12for index, animal in enumerate(animals, start=1):
13    print(f"{index}. {animal}")
14
15# While loop (less common)
16i = 0
17while i < len(animals):
18    print(animals[i])
19    i += 1

List Comprehensions - Preview

We'll talk about this in detail in the next lesson, but here's a quick preview:

1# Traditional way to create a list of squares
2squares = []
3for x in range(1, 6):
4    squares.append(x ** 2)
5# [1, 4, 9, 16, 25]
6
7# List comprehension - shorter and elegant!
8squares = [x ** 2 for x in range(1, 6)]
9# [1, 4, 9, 16, 25]

Nested Lists (2D Lists)

Sometimes you need a "list of lists" - like a map with a coordinate grid:

1# Terrain map (3x3)
2terrain_map = [
3    ["Forest", "River", "Forest"],
4    ["Mountain", "Camp", "Field"],
5    ["Forest", "Forest", "Road"]
6]
7
8# Accessing an element: [row][column]
9center = terrain_map[1][1]  # "Camp"
10top_left = terrain_map[0][0]  # "Forest"
11
12# Iterating through a 2D list
13for row in terrain_map:
14    for cell in row:
15        print(cell, end=" ")
16    print()  # New line after each row

Copying Lists - A Trap!

1# WARNING - this does NOT copy, it only creates a reference!
2original = ["A", "B", "C"]
3reference = original  # Same location in memory!
4
5reference[0] = "X"
6print(original)  # ["X", "B", "C"] - changed!
7
8# Proper copying:
9original = ["A", "B", "C"]
10copy1 = original.copy()  # copy() method
11copy2 = original[:]      # Slicing
12copy3 = list(original)   # list()
13
14copy1[0] = "X"
15print(original)  # ["A", "B", "C"] - unchanged!
16print(copy1)     # ["X", "B", "C"]

Practical Example - Discovery Journal

1# Expedition discovery journal management program
2
3print("=== DISCOVERY JOURNAL ===\n")
4
5# List of discovered species
6discovered_species = []
7
8while True:
9    print("\n1. Add discovery")
10    print("2. Show all discoveries")
11    print("3. Remove discovery")
12    print("4. Search for species")
13    print("5. Exit")
14
15    choice = input("\nChoice: ")
16
17    if choice == "1":
18        species = input("Species name: ")
19        discovered_species.append(species)
20        print(f"✓ Added: {species}")
21
22    elif choice == "2":
23        if len(discovered_species) == 0:
24            print("No discoveries!")
25        else:
26            print(f"\nDiscovered {len(discovered_species)} species:")
27            for i, species in enumerate(discovered_species, 1):
28                print(f"{i}. {species}")
29
30    elif choice == "3":
31        if len(discovered_species) == 0:
32            print("No discoveries to remove!")
33        else:
34            species = input("Name to remove: ")
35            if species in discovered_species:
36                discovered_species.remove(species)
37                print(f"✓ Removed: {species}")
38            else:
39                print("Not found!")
40
41    elif choice == "4":
42        species = input("Search: ")
43        if species in discovered_species:
44            pos = discovered_species.index(species) + 1
45            print(f"✓ Found at position {pos}")
46        else:
47            print("Not found!")
48
49    elif choice == "5":
50        print("\nSee you on the trail!")
51        break
52    else:
53        print("Invalid option!")

Practical Exercise

Create a "Safari Route Planner" program:

  1. Let the user add points to the route
  2. Display the entire route
  3. Let them insert a point in the middle of the route
  4. Let them remove a point
  5. Display the route in reverse order

Summary

In this lesson you learned:

  • ✅ What lists are and how to create them
  • ✅ Indexing and slicing
  • ✅ Modifying lists
  • ✅ List methods: append, extend, insert, remove, pop, sort, reverse
  • ✅ Operations: concatenation, repetition, in/not in
  • ✅ Iterating through lists
  • ✅ Nested lists
  • ✅ Copying lists (the proper way!)

Checkpoint

Before moving on:

  • [ ] You understand the difference between indexing and slicing
  • [ ] You can use at least 5 list methods
  • [ ] You know the difference between .sort() and sorted()
  • [ ] You know how to properly copy a list
  • [ ] You can iterate through a list with enumerate()

In the next lesson Darwin will show you dictionaries - a way to catalog discoveries with keys! 🗺️

Go to CodeWorlds