The cinema has a list of ticket quantities. We could inspect each position manually, but our program should still work when the next booking arrives. A for loop expresses “do this for each item.”
You need: lists, assignment, and arithmetic. By the end: you can process a sequence, calculate a summary, and distinguish one pass from repeated work. Allow 25–35 minutes.
Use the values directly
Save as daily_totals.py:
ticket_counts = [2, 4, 1]
total_tickets = 0
for count in ticket_counts:
total_tickets = total_tickets + count
print(total_tickets)
Output:
7
Python assigns each item to count in turn and runs the block. The running total becomes 2, then 6, then 7. The list is not consumed or changed by this loop.
The initial 0 is outside the loop. If you reset the total inside it, you lose the earlier work. If the list is empty, the loop runs zero times and the total remains 0.
For a plain numerical sum, Python already provides a clearer expression:
ticket_counts = [2, 4, 1]
print(sum(ticket_counts))
Learn the loop so you understand accumulation; use sum() when summing is all you need. Built-ins are often efficient, but their most immediate benefit is that the intent is obvious.
Repeat a known number of times
for seat_number in range(1, 5):
print(f"Seat {seat_number}")
This prints seats 1 through 4. range() excludes the stop value, just like slicing. range(3) produces 0, 1, 2 during iteration; range(2, 9, 2) produces 2, 4, 6, 8.
A range object describes the integer sequence without storing every integer in a list. Avoid list(range(...)) when your only purpose is to loop. That extra list adds memory use without helping the task.
Need a position too? Use enumerate
customers = ["Mina", "Luca", "Ana"]
for position, name in enumerate(customers, start=1):
print(f"{position}. {name}")
Output:
1. Mina
2. Luca
3. Ana
enumerate() supplies a counter alongside each value. The two names receive those two pieces of information; this is called unpacking. The display counter starts at 1 here, but the list’s underlying indexes still start at 0.
Prefer iterating over values directly when you do not need positions. range(len(customers)) plus repeated indexing introduces machinery without adding meaning for this task.
Do not change the collection you are walking through
Removing list items during iteration can skip items as their positions shift. To select matching values, collect them separately:
ticket_counts = [2, 0, 4, -1]
positive_counts = []
for count in ticket_counts:
if count > 0:
positive_counts.append(count)
print(positive_counts)
This prints [2, 4]. We deliberately keep the input unchanged. In a real pipeline, rejected values should also be counted or recorded; silently discarding them can hide a source problem.
Performance: one pass or many?
If you only need the total, you do not need to build positive_counts first. Filter and accumulate in one pass. Both approaches inspect all the values, but the extra list needs additional memory proportional to the number retained.
A loop inside another loop may examine every possible pair. For 1,000 records, that can mean 1,000,000 comparisons. It is not always wrong, but it deserves a reason. Later, dictionaries, sets, and joins will help us avoid many repeated searches.
Fewer operations can reduce runtime. In a billed compute job that may reduce cost, but the actual bill also depends on resource size, minimum billing periods, and other work. We will measure rather than promise savings from a toy example.
Your turn: count good data and bad data
For [2, 0, 4, -1, 1], calculate the total of positive counts and the number of rejected entries. Use one pass, without creating a second list.
Show one solution
ticket_counts = [2, 0, 4, -1, 1]
total_tickets = 0
rejected_entries = 0
for count in ticket_counts:
if count > 0:
total_tickets = total_tickets + count
else:
rejected_entries = rejected_entries + 1
print(f"Tickets: {total_tickets}")
print(f"Rejected entries: {rejected_entries}")
Expected results: 7 tickets and 2 rejected entries. An empty input gives 0 and 0. We use only two running numbers beyond the original input collection.
Checkpoint: explain when you would use a direct loop, enumerate(), or range(). Then explain why fewer lines of source code do not necessarily mean less work for the computer.