A game club has a whole row of scores to organize, compare, and improve. Your challenge is to keep related values together, visit every value, and build useful new collections without losing track of the original data.
By Lesson 3, you will turn a score list into filtered results and running totals with reusable functions.
-
Make a list, read or change an item by position, and add or remove items.
-
Visit list items in a loop and take a slice of a list.
-
Sort a list and find its largest or smallest item by checking items in order.
-
Build a new list containing only items that pass a test.
-
Lesson 1: Build and Read
Start the score board
A list keeps several values in order. Square brackets make a list literal, and commas separate its items.
scores = [3, 1, 2] print(scores)Scroll the code for more ↓
Output
[3, 1, 2]The three scores stay together in their written order.
An index reaches one position: index
0is the first position.print(scores[0])Scroll the code for more ↓
Output
3Index
0selects3, not the whole list. A negative index counts from the end, as it did for strings in Unit 09.print(scores[-1])Scroll the code for more ↓
Output
2Index
-1selects the last score,2. Uselento count the items.print(len(scores))Scroll the code for more ↓
Output
3There are three items. Assign through an index to change one existing item.
scores[1] = 5 print(scores)Scroll the code for more ↓
Output
[3, 5, 2]The second score changes, and the list is now
[3, 5, 2]. A function can take a list and return its first item.def first_score(scores): return scores[0] print(first_score(scores))Scroll the code for more ↓
Output
3first_score(scores)returns3. It expects a nonempty list, because an empty list has no position0.Loop over the values
When you need each value but not its position, loop directly over the list. The loop below visits one score at a time.
len(scores)gives the number of items, andsum(scores)gives their total.def total_with_values(scores): total = 0 for score in scores: total = total + score return total def score_report(scores): return f"{len(scores)} scores total {sum(scores)}" print(total_with_values([4, 7, 5])) print(score_report([4, 7, 5]))Scroll the code for more ↓
Output
16 3 scores total 16The calls return
16and the report3 scores total 16. The hand-written loop exposes the running total, whilesumperforms the same common job in one call. A direct value loop is the clearest choice when the positions do not matter.Build a new list with
appendThe method call
some_list.append(value)adds one item at the end of a list. Start with an empty list when the answer will be built one item at a time. Each loop trip calculates one new value and appends it.def double_values(numbers): doubled = [] for number in numbers: doubled.append(number * 2) return doubled print(double_values([2, 5, 8])) print(double_values([-3, 0, 4]))Scroll the code for more ↓
Output
[4, 10, 16] [-6, 0, 8]The calls return
[4, 10, 16]and[-6, 0, 8]. The input list supplies the values; the emptydoubledlist grows with oneappendcall per trip. The function returns a new list.Change a list in place
insert(0, value)places a value before the current first item.line = [4, 7, 9] line.insert(0, 2) print(line)Scroll the code for more ↓
Output
[2, 4, 7, 9]The line is now
[2, 4, 7, 9].pop()removes and returns the last item.last = line.pop() print(last, line)Scroll the code for more ↓
Output
9 [2, 4, 7]lastis9; the line now ends at7. Givepopan index to remove a different position.first = line.pop(0) print(first, line)Scroll the code for more ↓
Output
2 [4, 7]firstis2; the line is[4, 7].remove(value)removes the first matching value.line.append(4) line.remove(4) print(line)Scroll the code for more ↓
Output
[7, 4]Only the first
4was removed, leaving[7, 4].index(value)finds the position of the first match.print(line.index(4))Scroll the code for more ↓
Output
1The remaining
4is at index1.removeandindexraiseValueErrorfor a missing value, so checkif value in line:first.Loop over the positions
Sometimes a calculation needs both the current item and another position.
range(len(scores))supplies every valid index from0through one less than the list length. To compare each score with the previous score, begin at index1.def score_changes(scores): changes = [] for i in range(1, len(scores)): change = scores[i] - scores[i - 1] changes.append(change) return changes print(score_changes([8, 11, 10, 15])) print(score_changes([6]))Scroll the code for more ↓
Output
[3, -1, 5] []The calls return
[3, -1, 5]and[]. The index loop is useful becausescores[i]andscores[i - 1]reach neighboring positions. A one-item list has no pair to compare, so its result stays empty.Slices and list equality
A slice selects a section into a new list; the end index is excluded.
print(scores[1:3])Scroll the code for more ↓
Output
[5, 2]The result is
[5, 2];scoresis unchanged. A step of-1makes a new list in reverse order.print(scores[::-1]) print(scores)Scroll the code for more ↓
Output
[2, 5, 3] [3, 5, 2]The reversed list is
[2, 5, 3], whilescoresremains[3, 5, 2]. Two lists compare equal when their items match in the same order.print([1, 2] == [1, 2], [1, 2] == [2, 1])Scroll the code for more ↓
Output
True FalsePython prints
True False; changing the order changes the list.Read several numbers on one line
split()separates one line at its spaces into a list of strings.line = "7 3 8" parts = line.split() print(parts)Scroll the code for more ↓
Output
['7', '3', '8']partsis["7", "3", "8"]; its items are strings. Convert individual pieces before doing arithmetic.print(int(parts[0]) + int(parts[1]))Scroll the code for more ↓
Output
10The first two numbers add to
10. To convert every piece, append each converted value in a loop.numbers = [] for part in parts: numbers.append(int(part)) print(numbers)Scroll the code for more ↓
Output
[7, 3, 8]numbersholds[7, 3, 8]as integers.joincan put a separator between the string pieces in a list.print("-".join(parts))Scroll the code for more ↓
Output
7-3-8The string result is
7-3-8. Herejoinreceives a list of strings; Unit 09 joined letters from one string. A real program can read that line withinput().Try it parts = input("Numbers: ").split() numbers = [] for part in parts: numbers.append(int(part)) print(sum(numbers))Scroll the code for more ↓
This input cell waits for a line such as
7 3 8and prints its total. Another common format puts the count first, followed by one number per line.Try it n = int(input("How many numbers? ")) numbers = [] for i in range(n): numbers.append(int(input("Number: "))) print(numbers)Scroll the code for more ↓
The second input cell reads exactly
nvalues into one list.Lesson 2: Order and Choose
A tournament organizer needs a low-to-high score board and the position of the winning score. Sorting can order the values, but choosing a position requires a careful index loop.
Notice:
sortchanges a list and returnsNoneThe list method
sortrearranges the existing list in place. Its returned value isNone, which means it does not hand back a useful new list. Predict the two printed lines.nums = [9, 2, 6] scores = nums.sort() print(nums) print(scores)Scroll the code for more ↓
Output
[2, 6, 9] NonePython prints
[2, 6, 9]and thenNone. The call changednums, butscores = nums.sort()saved the method's missing return value. This is theNonetrap: do not assign the result ofsortwhen you want the changed list.Sort in place when changing the input is the job
Call
sortas its own statement, then return the now-ordered list if the caller needs that value.def order_in_place(scores): scores.sort() return scores print(order_in_place([12, 5, 8])) print(order_in_place([-2, -9, -4]))Scroll the code for more ↓
Output
[5, 8, 12] [-9, -4, -2]The calls return
[5, 8, 12]and[-9, -4, -2]. This function deliberately changes the list it receives. Its name says that in-place change is part of the job.Use
sortedwhen the original order must stayThe built-in function
sorted(scores)returns a new ordered list. It leaves the original list in its old order.def ordered_copy(scores): return sorted(scores) original_scores = [14, 7, 11] new_order = ordered_copy(original_scores) print(original_scores) print(new_order)Scroll the code for more ↓
Output
[14, 7, 11] [7, 11, 14]Python prints
[14, 7, 11]and[7, 11, 14]. Choosesortfor an intentional in-place change andsortedfor a separate ordered result.A real program can read one line of numbers, convert every piece, and print the ordered copy.
Try it parts = input("Numbers: ").split() numbers = [] for part in parts: numbers.append(int(part)) print(sorted(numbers))Scroll the code for more ↓
sortedreturns a new list in low-to-high order.Built-in list calculations
For a list with at least one number,
minreturns its smallest item andmaxreturns its largest item.sumreturns the total. These built-ins answer common value questions, but they do not tell you the position of a winning value.def number_summary(numbers): return [min(numbers), max(numbers), sum(numbers)] print(number_summary([7, 2, 10, 4])) print(number_summary([-8, -3, -12]))Scroll the code for more ↓
Output
[2, 10, 23] [-12, -3, -23]The calls return
[2, 10, 23]and[-12, -3, -23]. The second call is a reminder that the largest negative number is still negative.Find an extreme by hand
A hand-written extreme loop remembers the best value seen so far. This function assumes the list has at least one item, so
numbers[0]is a real starting value. Never startbestat0: a list of negative numbers might not contain any value as large as 0.def find_largest(numbers): best = numbers[0] for number in numbers: if number > best: best = number return best print(find_largest([5, 12, 9])) print(find_largest([-11, -4, -7]))Scroll the code for more ↓
Output
12 -4The calls return
12and-4. Seeding from the first item makes the loop correct for negative values too. The built-inmaxis shorter when only the value matters; the hand-written loop can be adapted when the position matters.Find the position of the maximum
An argmax is the position of a largest value. Remember a position rather than the value itself, then compare through list indexes. This function assumes the list has at least one item.
def position_of_largest(numbers): best_position = 0 for i in range(1, len(numbers)): if numbers[i] > numbers[best_position]: best_position = i return best_position print(position_of_largest([13, 21, 18])) print(position_of_largest([-2, -7, -1]))Scroll the code for more ↓
Output
1 2The calls return
1and2. Because the comparison uses>rather than>=, equal largest values leave the earliest winning position in place.Apply argmax to words
The same position loop can compare calculated qualities instead of number values. To find the longest word, compare the lengths of the words at two positions. The list must have at least one item.
def position_of_longest(words): best_position = 0 for i in range(1, len(words)): if len(words[i]) > len(words[best_position]): best_position = i return best_position print(position_of_longest(["ant", "butterfly", "moth"])) print(position_of_longest(["red", "blue", "gold"]))Scroll the code for more ↓
Output
1 1The calls return
1and1. In the second list,blueandgoldtie at length 4, so the earlier position wins. This is why an index loop can solve more than the built-in value questions.Lesson 3: Filter and Combine
A coach needs a clean list of qualifying scores and a progress line that shows the total after every round. Both jobs build a new list one decision at a time.
Count values that pass a test
A counter can record how many items pass a condition. It starts at 0 and increases only when the current score reaches the minimum.
def count_qualifiers(scores, minimum): count = 0 for score in scores: if score >= minimum: count = count + 1 return count print(count_qualifiers([8, 13, 11, 6], 10)) print(count_qualifiers([4, 5, 3], 7))Scroll the code for more ↓
Output
2 0The calls return
2and0. Counting answers how many values pass; filtering keeps the passing values themselves.Filter into a new list
To filter, start with an empty result list. Loop over the input, test each item, and call
appendonly inside theifbody. This example also practices membership within.On a list,
intests whole-item list membership — “is this value one of the items?” — unlike Unit 09, whereintested character or substring membership inside a string.def keep_allowed(values, allowed): kept = [] for value in values: if value in allowed: kept.append(value) return kept print(keep_allowed([4, 9, 2, 9, 7], [2, 4, 7])) print(keep_allowed([5, 6], [1, 2, 3]))Scroll the code for more ↓
Output
[4, 2, 7] []The calls return
[4, 2, 7]and[]. The result keeps the input order and includes only values that belong toallowed. Building with an explicit loop makes every filtering decision visible.Build prefix sums
A prefix sum is the total so far after each item. Update the running total first, then append that total once per loop trip.
def prefix_sums(numbers): totals = [] running_total = 0 for number in numbers: running_total = running_total + number totals.append(running_total) return totals print(prefix_sums([3, 5, 2, 6])) print(prefix_sums([-2, 7, -1]))Scroll the code for more ↓
Output
[3, 8, 10, 16] [-2, 5, 4]The calls return
[3, 8, 10, 16]and[-2, 5, 4]. Each returned item answers, “What is the total through this position?”Lists inside lists: a grid
Each inner list can hold one row of a grid. Read a complete row with one index.
grid = [[1, 1, 0], [0, 1, 1]] print(grid[1])Scroll the code for more ↓
Output
[0, 1, 1]Row
1is[0, 1, 1]. A second index selects a column inside that row.print(grid[1][0])Scroll the code for more ↓
Output
0Row
1, column0holds0. Nested loops can turn each numeric row into a text row.rows = [] for grid_row in grid: row_text = "" for value in grid_row: if value == 1: row_text = row_text + "#" else: row_text = row_text + "." rows.append(row_text) print("\n".join(rows))Scroll the code for more ↓
Output
##. .##The picture prints as
##.and.##on separate lines."\n".join(rows)makes one string for the whole picture. A board can also store each row as a string.board = ["#..", ".#.", "..#"] print(board[2][2])Scroll the code for more ↓
Output
#The bottom-right cell is
#. To read a board, read its row count, then one row string per line.Try it row_count = int(input("Rows: ")) board = [] for i in range(row_count): board.append(input("Row: ")) print(board)Scroll the code for more ↓
This input cell builds a list of row strings, ready for
board[row][column].Put it together: keep above-average scores
This function assumes the list has at least one item. First calculate the average with
sum(scores) / len(scores). Then filter every score that is strictly greater than that average into a new list.def above_average(scores): average = sum(scores) / len(scores) kept = [] for score in scores: if score > average: kept.append(score) return kept print(above_average([10, 16, 12, 18])) print(above_average([7, 7, 7]))Scroll the code for more ↓
Output
[16, 18] []The first average is
14.0, so the function returns[16, 18]. The second average is7.0, so no score is strictly above it and the function returns[].Put it together: lists keep ordered data, value loops visit items, index loops connect values to positions, and
appendbuilds new results. Sorting, finding an extreme, filtering, and prefix sums are different questions built from those same tools.-
[3, 1, 2]keeps three values in order;scores[0]reads the first one. -
appendgrows a list, while a loop can visit each item or its position. -
scores.sort()changes the list;sorted(scores)makes an ordered copy. -
To find an extreme, keep the best value or position seen so far.
-
To filter, test each item and append only the ones you want to a new list.
You can now organize the game club's scores and build a list of qualifying scores.
-