One variable called customer_name can remember the most recent customer. It cannot, by itself, remember the whole audience. Creating customer_1, customer_2, and 400 more names is how a small script becomes a cry for help.
You need: variables, strings, and loops. By the end: you can store an ordered collection, retrieve items, and choose sensible operations. Allow 25–35 minutes.
An ordered collection
A list holds a sequence of values. Square brackets create it; commas separate the items. Save this as guest_list.py:
customers = ["Mina", "Luca", "Ana"]
print(customers)
print(len(customers))
print(customers[0])
print(customers[-1])
Output:
['Mina', 'Luca', 'Ana']
3
Mina
Ana
len() returns the number of items. An index identifies a position, starting at zero. For three items, the valid non-negative indexes are 0, 1, and 2. Negative indexes count from the end: -1 means the last item.
Reading customers[3] here raises IndexError. An empty list, [], has no first or last item. Check the length or structure your program so an item is known to exist before retrieving it.
Update the collection
Lists are mutable: you can change their contents.
customers = ["Mina", "Luca"]
customers.append("Ana")
customers[1] = "Lucas"
cancelled_customer = customers.pop()
print(customers)
print(cancelled_customer)
Output:
['Mina', 'Lucas']
Ana
append() adds an item at the end. pop() removes and returns the final item. pop(0) removes and returns the first. remove("Mina") instead finds and removes the first equal value, and raises ValueError if it is absent.
Not every method returns the updated list. append() changes the existing list and returns None, Python’s value for the absence of a meaningful result. Do not write customers = customers.append("Ana"): that replaces your list variable with None.
Take a slice
customers = ["Mina", "Luca", "Ana", "Noah"]
first_pair = customers[0:2]
everyone_after_first = customers[1:]
print(first_pair)
print(everyone_after_first)
print(customers)
The first output is ['Mina', 'Luca']; the second is ['Luca', 'Ana', 'Noah']. The original list still contains all four names.
The start is included; the stop is excluded. A list slice creates a new list. It copies references to the selected items, not a recursive copy of everything those items might contain. Our items are strings; lesson 14 will explore nested mutable values.
Check membership
customers = ["Mina", "Luca"]
name = "Ana"
if name not in customers:
customers.append(name)
print(customers)
in asks whether an equal value is present. not in asks the opposite. For this toy guest list, we reject repeated names. A real booking system should use a booking ID: two different customers can share a name.
Performance and memory choices
Think about what an operation asks Python to do:
| Operation | Work to keep in mind |
|---|---|
customers[0] | Direct access to one position. |
customers.append(name) | Usually cheap; occasional resizing means more work on some appends. |
name in customers | May compare against every item. |
customers.pop(0) | Shifts the remaining items toward the front. |
customers[:] | Creates another list containing references to all items. |
For three names, the difference is negligible. For a large queue, repeated front removals can create substantial unnecessary work; we will later use collections.deque for that job. Repeated full-list copies also use extra memory. Choosing the right structure often matters more than shortening the code.
Your turn: a waiting list
Start with ['Mina', 'Luca'], add Ana, then remove and print the last person. Print the remaining list. Finally, print its first two items without modifying it.
Show one solution
waiting = ["Mina", "Luca"]
waiting.append("Ana")
removed = waiting.pop()
print(removed)
print(waiting)
print(waiting[:2])
The removed person is Ana; both lists printed afterward contain Mina and Luca. The slice is a separate list even though its displayed contents match.
Checkpoint: explain why the first index is 0, why append() should not be assigned back, and why making a full copy on every new booking would be wasteful.