Every arcade game needs a leaderboard. A messy scrap of paper can hold a few scores, but our program needs to remember every score, grow when a new player finishes, and crown a champion. We build that hall with a Python list.
Each idea comes as a short ladder — simplest first, then one step up, then the real board — with a Notice naming the one new thing.
You will learn
- Build a list with
[...]and read its items by position. - Grow a list with
.append()and visit every item with aforloop. - Measure a list with
len,maxandmin, and work out an average. - Rank a list with
.sort()and print a numbered hall of fame.
Lesson 1: Build the Score Board
A list lets one variable hold many items in order. Square brackets mark its start and end; commas separate the items.
scores = []
print(scores)
Output
[]Notice
[] is an empty list — a board with no scores yet.
scores = [1200, 850]
print(scores)
Output
[1200, 850]Notice
Put items inside the brackets, separated by commas.
scores = [1200, 850, 990, 1500]
print(f"Arcade scores: {scores}")
Output
Arcade scores: [1200, 850, 990, 1500]Notice
A list can hold as many items as you like — here, the four arcade scores.
List positions start at 0. Square brackets with a position select one item.
scores = [1200, 850, 990, 1500]
print(scores[0])
Output
1200Notice
scores[0] is the FIRST item (position 0).
print(scores[2])
Output
990Notice
Each position picks the item sitting there — scores[2] is the third.
print(scores[-1])
Output
1500Notice
-1 counts back from the end — the LAST score.
The list method .append() adds a new item to the END of the same list.
scores = [1200, 850]
scores.append(990)
print(scores)
Output
[1200, 850, 990]Notice
.append(990) adds 990 to the end of scores.
best = 1500
scores.append(best)
print(scores)
Output
[1200, 850, 990, 1500]Notice
You can append a value held in a variable too, not only a literal.
board = []
new_scores = [1200, 850, 990]
for one_score in new_scores:
board.append(one_score)
print(board)
Output
[1200, 850, 990]Notice
A for loop can append many items in a row to build a list.
A for loop can also VISIT each item in a list, one at a time.
scores = [1200, 850, 990, 1500]
for one_score in scores:
print(f"Score: {one_score}")
Output
Score: 1200
Score: 850
Score: 990
Score: 1500Notice
The loop runs once per item, with one_score holding each value in turn.
scores = [1200, 850, 990, 1500]
total = 0
for one_score in scores:
total = total + one_score
print(f"Total points: {total}")
Output
Total points: 4540Notice
Add each item into an accumulator to build a running total over the whole list.
scores = [1200, 850, 990, 1500]
for i in range(len(scores)):
print(scores[i])
Output
1200
850
990
1500Notice
You can also loop by POSITION with range(len(scores)), reading each item as scores[i].
scores = [1200, 850, 990, 1500]
for i in range(len(scores)):
print(f"Entry #{i + 1}: {scores[i]}")
Output
Entry #1: 1200
Entry #2: 850
Entry #3: 990
Entry #4: 1500Notice
One step more — add 1 to the position for a friendly entry number beside each score.
Built-in functions measure a list. len counts items, max finds the biggest, min the smallest.
scores = [1200, 850, 990, 1500]
print(len(scores))
Output
4Notice
len(scores) is how many items the list holds.
print(max(scores))
Output
1500Notice
max(scores) finds the champion — the biggest score.
print(min(scores))
Output
850Notice
min(scores) finds the smallest score.
Dividing the total by the count gives the average. Python writes that as a decimal, called a float.
scores = [1200, 850, 990, 1500]
total = 0
for one_score in scores:
total = total + one_score
average = total / len(scores)
print(f"Average score: {average}")
Output
Average score: 1135.0Notice
/ gives a float (a decimal) — the average of the four scores.
Try it yourself
n = int(input("How many scores? "))
scores = []
for i in range(n):
score = int(input(f"Score {i + 1}: "))
scores.append(score)
total = 0
for one_score in scores:
total = total + one_score
average = total / len(scores)
print(f"Average score: {average}")
Notice
The real version reads however many scores the player types into a list, then uses the same running-total and average logic. (Reads live input, so it does not run here.)
Lesson 2: Rank the Hall and Crown the Champion
The list method .sort() rearranges the SAME list in place (it changes the list, and returns None, so call it on its own line).
scores = [1200, 850, 990, 1500]
scores.sort()
print(f"Low to high: {scores}")
Output
Low to high: [850, 990, 1200, 1500]Notice
.sort() puts the items in order, lowest first.
scores.sort(reverse=True)
print(f"Top score first: {scores}")
Output
Top score first: [1500, 1200, 990, 850]Notice
.sort(reverse=True) orders them highest first — the leaderboard order.
scores = [1200, 850, 990, 1500]
scores.sort(reverse=True)
print(f"Champion: {scores[0]}")
print(f"Runner-up: {scores[1]}")
Output
Champion: 1500
Runner-up: 1200Notice
Once the list is sorted top-first, scores[0] is the champion and scores[1] the runner-up — sorting makes the ranks easy to read.
Unlike Unit 06's string methods (which RETURN a changed string), .sort() mutates the list in place and returns None — so write scores.sort(), never best = scores.sort().
Put it together: a helper prints one ranked line, and we loop the sorted board to show every place.
def board_line(place, score):
return "Place " + str(place) + ": " + str(score)
scores = [1500, 1200, 990, 850]
for place in range(len(scores)):
print(board_line(place + 1, scores[place]))
Output
Place 1: 1500
Place 2: 1200
Place 3: 990
Place 4: 850Put it together: a ranked hall must stay top-first when a new score arrives. This helper appends the score and immediately re-sorts the same list before returning it.
def board_line(place, score):
return "Place " + str(place) + ": " + str(score)
def add_score(scores, new_score):
scores.append(new_score)
scores.sort(reverse=True)
return scores
scores = [1500, 1200, 990, 850]
scores = add_score(scores, 1310)
for place in range(len(scores)):
print(board_line(place + 1, scores[place]))
Output
Place 1: 1500
Place 2: 1310
Place 3: 1200
Place 4: 990
Place 5: 850Notice
Append + re-sort keeps the hall ranked after every new score.
Try it yourself
def board_line(place, score):
return "Place " + str(place) + ": " + str(score)
def add_score(scores, new_score):
scores.append(new_score)
scores.sort(reverse=True)
return scores
n = int(input("How many scores? "))
scores = []
for i in range(n):
score = int(input(f"Score {i + 1}: "))
scores.append(score)
scores = add_score(scores, 1310)
for place in range(len(scores)):
print(board_line(place + 1, scores[place]))
Notice
The real version reads the starting board with input(), then the same helper appends 1310 and re-sorts the hall. (Reads live input, so it does not run here.)
Lesson 3: Polish the Hall
A tier rewards one score: at least 1000 earns gold, at least 500 silver, else bronze.
score = 990
if score >= 1000:
tier = "gold"
elif score >= 500:
tier = "silver"
else:
tier = "bronze"
print(f"A score of {score} earns the {tier} tier.")
Output
A score of 990 earns the silver tier.Before adding a score, membership can guard against recording it twice. in belongs inside the if condition.
scores = [1500, 1310, 1200, 990, 850]
new_score = 1310
if new_score in scores:
print(f"The score {new_score} is already on the board.")
else:
print(f"Adding {new_score}.")
Output
The score 1310 is already on the board.Try it yourself
n = int(input("How many scores? "))
scores = []
for i in range(n):
score = int(input(f"Score {i + 1}: "))
scores.append(score)
new_score = 1310
if new_score in scores:
print(f"The score {new_score} is already on the board.")
else:
print(f"Adding {new_score}.")
Notice
The real version reads the board with input() before making the same duplicate-membership check. (Reads live input, so it does not run here.)
Imagine a challenge where the qualifying score doubles each round. A while loop doubles a threshold until it reaches the champion score.
champion = 1500
threshold = 10
while threshold < champion:
threshold = threshold * 2
print(f"First doubled threshold at or above {champion}: {threshold}")
Output
First doubled threshold at or above 1500: 2560Here is a deliberate bug. A list with len(scores) items has positions 0 through len(scores) - 1, so the next cell asks for a position just past the end. Leave it unrun and predict the error.
Read the error
scores = [1500, 1200, 990, 850]
scores[len(scores)]
Read the traceback from the bottom: IndexError: list index out of range means the position does not exist. scores[-1] would select the final score instead.
Algorithm Extension
Extra loop practice — optional enrichment: these drills reuse the same loop shapes on small fixed data, so try as many as you like.
Pattern Spotlight: Find the best (max / argmax)
Keep the best so far while scanning — and remember WHO, not just the number. max(scores) gives the biggest number, but an explicit scan can keep the matching player name too. With parallel names and scores lists, loop through their positions; whenever the current score beats best_score, update both best_score and best_name.
names = ["Ada", "Bo", "Cy"]
scores = [3, 9, 5]
best_name = names[0]
best_score = scores[0]
print(best_name, best_score)
Output
Ada 3Notice
Seed the champion from the FIRST player — best_name/best_score start as Ada 3; never best_score = 0 (a real score could be lower).
names = ["Ada", "Bo", "Cy"]
scores = [3, 9, 5]
best_name = names[0]
best_score = scores[0]
if scores[1] > best_score:
best_name = names[1]
best_score = scores[1]
print(best_name, best_score)
Output
Bo 9Notice
Compare the next player; 9 > 3, so a new champion — update the NAME and the score together, giving Bo 9.
names = ["Ada", "Bo", "Cy"]
scores = [3, 9, 5]
i = 2
print(names[i], scores[i])
Output
Cy 5Notice
names[i] and scores[i] are the SAME player (Cy 5) — the loop will walk i over both lists in step.
names = ["Ada", "Bo", "Cy"]
scores = [3, 9, 5]
best_name = names[0]
best_score = scores[0]
for i in range(len(scores)):
if scores[i] > best_score:
best_name = names[i]
best_score = scores[i]
print(best_name, best_score)
Output
Bo 9Notice
One pass keeps the highest-scoring player's NAME and score — the champion Bo 9, not just the number.
Try it yourself
n = int(input("How many players? "))
names = []
scores = []
for i in range(n):
names.append(input(f"Name {i + 1}: "))
scores.append(int(input(f"Score {i + 1}: ")))
best_name = names[0]
best_score = scores[0]
for i in range(len(scores)):
if scores[i] > best_score:
best_name = names[i]
best_score = scores[i]
print(best_name, best_score)
Notice
The real version reads each player's name and score together with input(), then the same one-pass scan keeps the champion pair. (Reads live input, so it does not run here.)
Pattern Spotlight: Keep the ones that pass (filter)
The job is to build a NEW list of only the items that pass a test. Start with an empty list, check each score inside a loop, and append the score only when the condition passes.
Computational-thinking contrast: A person might glance across score cards and sort the qualifying cards into a new pile. A program checks one score at a time and appends each passing score to a new list.
kept = []
kept.append(9)
print(kept)
Output
[9]Notice
Start an empty result list and append a keeper — kept is now [9].
kept = []
kept.append(9)
score = 3
if score >= 5:
kept.append(score)
print(kept)
Output
[9]Notice
Check BEFORE appending; 3 >= 5 is False, so 3 is not kept — kept stays [9].
scores = [3, 9, 5, 7]
kept = []
for s in scores:
if s >= 5:
kept.append(s)
print(kept)
Output
[9, 5, 7]Notice
One pass copies just the qualifying scores (>= 5) into the new list — [9, 5, 7].
Try it yourself
n = int(input("How many scores? "))
scores = []
for i in range(n):
score = int(input(f"Score {i + 1}: "))
scores.append(score)
kept = []
for s in scores:
if s >= 5:
kept.append(s)
print(kept)
Notice
The real version reads the score list with input(), then the same filter copies only scores that pass. (Reads live input, so it does not run here.)
Recap
- A list holds many items in order;
scores[0]is the first andscores[-1]the last. .append()adds an item to the end of the same list.for one_score in scores:visits each item, andrange(len(scores))gives each position.len,maxandminmeasure a list; the total divided by the count gives a float average.scores.sort(reverse=True)puts the top score first and returnsNone, so call it on its own line.
You can now build a leaderboard that crowns a champion.