Python, Concept by Concept › Lists
Exercises: Lists
Core work is Exercises 1–10. Exercises 11–30 are More Practice; Exercises 31–37 are optional Challenges. Define each named function and try every worked sample call.
Keep the exact function name and parameters, return the promised value, and call the function with the shown inputs. The arrows show what each call must return. Add a short purpose comment and use meaningful local names. Build new lists with append (or change them in place with the Lesson 1 methods when a spec says so).
Exercise 1: Score Snapshot
A score keeper wants one small list containing the first score, the number of scores, and the total.
Specification: Define score_snapshot(scores). The list has at least one item. Return a new list containing scores[0], len(scores), and sum(scores), in that order.
Worked sample calls:
score_snapshot([6, 9, 4]) -> [6, 3, 19]
score_snapshot([12]) -> [12, 1, 12]
score_snapshot([-2, 5, 1, 3]) -> [-2, 4, 7]
Real program
The real program reads one line of scores with input().
How this is checked: Checked by tests that run your function score_snapshot.
Exercise 2: Scale Every Score
A game designer needs a new score list after applying the same multiplier to every value.
Specification: Define scaled_scores(scores, factor). Start with an empty result list. Loop directly over the score values, append score * factor once per trip, and return the new list.
Worked sample calls:
scaled_scores([3, 7, 2], 4) -> [12, 28, 8]
scaled_scores([-2, 5, 0], 3) -> [-6, 15, 0]
scaled_scores([], 9) -> []
Real program
The real program reads one line of scores and a multiplier on the next line with input().
How this is checked: Checked by tests that run your function scaled_scores.
Exercise 3: Round-to-Round Changes
A practice tracker needs the change from each round to the next round.
Specification: Define round_changes(scores). The list has at least one item. Use an index loop beginning at position 1. For each position, append the current score minus the previous score. Return the new list of changes.
Worked sample calls:
round_changes([5, 9, 8, 14]) -> [4, -1, 6]
round_changes([20, 15, 10]) -> [-5, -5]
round_changes([7]) -> []
Real program
The real program reads one line of scores with input().
How this is checked: Checked by tests that run your function round_changes.
Exercise 4: Repair the In-Place Sorter
A tournament sorter uses return scores.sort(), so callers receive None instead of the ordered list.
Specification: Define sort_in_place(scores). Call scores.sort() as its own statement, then return scores on the next line. The function deliberately changes the list it receives.
Worked sample calls:
sort_in_place([8, 3, 6]) -> [3, 6, 8]
sort_in_place([-1, -7, -4]) -> [-7, -4, -1]
sort_in_place([5, 5, 2]) -> [2, 5, 5]
Real program
The real program reads one line of scores with input().
How this is checked: You check this one yourself, against the list below.
The site cannot check this one. Run your program, then tick each item below when your work does it.
Exercise 5: Winning Position
A results screen needs the position of the largest score, not just the score itself.
Specification: Define position_of_largest(scores). The list has at least one item. Start best_position at 0. Use an index loop and compare the score at the current position with the score at best_position. Update only for a strictly larger score, so a tie keeps the earliest position. Return best_position.
Worked sample calls:
position_of_largest([14, 22, 17]) -> 1
position_of_largest([-8, -3, -10]) -> 1
position_of_largest([9, 12, 12, 4]) -> 1
Real program
The real program reads one line of scores with input().
How this is checked: Checked by tests that run your function position_of_largest.
Exercise 6: Progress Totals
A reading challenge records pages from each session and needs the total so far after every session.
Specification: Define progress_totals(pages). Start an empty result list and a running total of 0. For each page count, update the running total first and then append it. Return the list of prefix sums.
Worked sample calls:
progress_totals([4, 6, 3]) -> [4, 10, 13]
progress_totals([10, 0, 5, 2]) -> [10, 10, 15, 17]
progress_totals([]) -> []
Real program
The real program reads one line of page counts with input().
How this is checked: Checked by tests that run your function progress_totals.
Exercise 7: Above the Team Average
A coach wants a new list containing only scores that are strictly above the team's average.
Specification: Define above_average(scores). The list has at least one item. Calculate the average with sum(scores) / len(scores). Build a new list by appending each score that is strictly greater than the average. Keep the original order and return the new list.
Worked sample calls:
above_average([9, 15, 12, 20]) -> [15, 20]
above_average([4, 4, 4]) -> []
above_average([-6, -2, -4]) -> [-2]
Real program
The real program reads one line of scores with input().
How this is checked: Checked by tests that run your function above_average.
Exercise 8: Numbers on One Line
A score feed arrives as one space-separated line, but calculations need integers.
Specification: Define parse_numbers(line). Use line.split(), then loop over the pieces, convert each with int, and append to a new list. Return the list. Put a short purpose comment above the function.
Worked sample calls:
parse_numbers("4 9 2 15") -> [4, 9, 2, 15]
parse_numbers("-3 0") -> [-3, 0]
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function parse_numbers.
Exercise 9: Second Largest
A results board needs the largest score strictly below its top score.
Specification: Define second_largest(numbers) for a list with at least two distinct values. Set top = max(numbers) and best = min(numbers). In a loop, keep a value only when it is below top and above best. Return best. With exactly two distinct values, the smaller value is the answer. Put a purpose comment above the function. In the stand-in and real program, print the result with an f-string label such as Second largest: 12.
Worked sample calls:
second_largest([7, 19, 4, 19, 12]) -> 12
second_largest([5, 3]) -> 3
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function second_largest.
Exercise 10: Rotate a List
A turn queue moves its first member to the end.
Specification: Define rotate_left(numbers) for a nonempty list. Use numbers.append(numbers.pop(0)), then return the same, changed list. Put a purpose comment above the function.
Worked sample calls:
rotate_left([3, 8, 1, 6]) -> [8, 1, 6, 3]
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: You check this one yourself, against the list below.
The site cannot check this one. Run your program, then tick each item below when your work does it.
Exercise 11: More Practice: Median
A data report needs its middle value, even when there are two middle values.
Specification: Define median(numbers) for a nonempty list. Use sorted(numbers) and middle index len(numbers) // 2. For odd length return the middle item itself (integer 5, not 5.0); for even length return the average of the two middles. Print f"Median: {m}" in the stand-in and real program.
Worked sample calls:
median([9, 2, 7, 4, 5]) -> 5; printed: Median: 5
median([8, 3, 6, 1]) -> 4.5; printed: Median: 4.5
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function median.
Exercise 12: More Practice: Mode
A survey asks which value occurs most often.
Specification: Define mode(numbers) for a nonempty list. For each value, use an inner loop and a count variable to count equal items. Update the best only for a strictly greater count, so the first tied value wins. Do not use a list count method.
Worked sample calls:
mode([4, 2, 4, 7, 2, 4]) -> 4
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function mode.
Exercise 13: More Practice: Remove Duplicates
A signup list needs each number just once, in first-appearance order.
Specification: Define dedupe(numbers). Start an empty result; append a number only if it is not in the result. Return the result.
Worked sample calls:
dedupe([5, 3, 5, 8, 3, 1]) -> [5, 3, 8, 1]
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function dedupe.
Exercise 14: More Practice: Reverse in Place
A display reverses its existing list without creating another list.
Specification: Define reverse_in_place(numbers). Use left and right indexes in a while left < right loop. Swap the two items through a temporary variable, then move both indexes inward. Return the same list. Do not use slices or reverse().
Worked sample calls:
reverse_in_place([6, 1, 9, 4]) -> [4, 9, 1, 6]
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: You check this one yourself, against the list below.
The site cannot check this one. Run your program, then tick each item below when your work does it.
Exercise 15: More Practice: Top Three
A podium shows its three highest scores, greatest first.
Specification: Define top_three(numbers) for at least three items. Use sorted(numbers), then return a list containing indexes -1, -2, and -3 in that order.
Worked sample calls:
top_three([14, 3, 27, 9, 18, 21]) -> [27, 21, 18]
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function top_three.
Exercise 16: More Practice: Queue at the Counter
A service counter changes its waiting line during a rush.
Specification: Define after_rush(names). Append "Fay", serve the first name with pop(0), insert "Eve" at index 0, and remove "Cal". Return the changed list. The sample line starts with exactly the three names shown.
Worked sample calls:
after_rush(["Ada", "Ben", "Cal"]) -> ['Eve', 'Ben', 'Fay']
Real program
The real program reads the three starting names on one line with input().
How this is checked: Checked by tests that run your function after_rush.
Exercise 17: More Practice: Find the Seat
A seating list gives a position for known names and -1 for a missing name.
Specification: Define seat_of(names, target). Guard .index(target) with if target in names:; return -1 otherwise.
Worked sample calls:
seat_of(["Kim", "Lu", "Max"], "Lu") -> 1
seat_of(["Kim", "Lu", "Max"], "Zed") -> -1
Real program
The real program reads the names on one line, then the target name with input().
How this is checked: Checked by tests that run your function seat_of.
Exercise 18: More Practice: Bar Chart
A weekly report displays one horizontal bar per day.
Specification: Define bar_chart(labels, values) for lists of the same length. Use an index loop. Build each row as f"{labels[i]} " + "#" * values[i], append the rows, and return "\n".join(rows) with no trailing spaces. In the stand-in, print the returned picture.
Worked sample calls:
bar_chart(["Mon", "Tue", "Wed"], [3, 5, 2]) -> "Mon ###\nTue #####\nWed ##"
Real program
The real program reads one line of labels, then one line of space-separated values with input().
How this is checked: Checked by tests that run your function bar_chart.
Exercise 19: More Practice: Grid Printer
A tile map uses 1 for a filled square and 0 for an empty square.
Specification: Define grid_text(grid) for a list of numeric rows. Use nested loops to build one row string per inner list, using # for 1 and . for 0. Append each row and return one string made with "\n".join(rows).
Worked sample calls:
grid_text([[1, 0, 1], [0, 1, 0]]) -> "#.#\n.#."
Real program
The real program reads a row count, then one space-separated numeric row per line with input().
How this is checked: Checked by tests that run your function grid_text.
Exercise 20: More Practice: Tic-Tac-Toe Winner
A board is three row strings, each containing X, O, or a dot.
Specification: Define winner(board). Build each of the three rows, three columns, and two diagonals as three-character lines. Return "X" or "O" if one of those lines holds three matching marks; otherwise return "none". Use an if/elif chain for the two winning marks, and check rows, columns, and diagonals.
Worked sample calls:
winner(["XOX", "OXO", "OOX"]) -> "X"
winner(["OOO", "XX.", "X.."]) -> "O"
winner(["XOX", "XOO", "OXX"]) -> "none"
Real program
The real program reads the row count 3, then one board row per line with input().
How this is checked: Checked by tests that run your function winner.
Exercise 21: More Practice: Magic Square Check
A 3-by-3 number board is magic when all rows, columns, and diagonals share one sum.
Specification: Define is_magic(grid) for exactly three rows of three integers. Set the target to the first row sum. Check every row. For each column, use a hand-written running total loop; also build both diagonal totals by hand. Return whether all totals equal the target.
Worked sample calls:
is_magic([[2, 7, 6], [9, 5, 1], [4, 3, 8]]) -> True
is_magic([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) -> False
Real program
The real program reads the row count 3, then one space-separated numeric row per line with input().
How this is checked: Checked by tests that run your function is_magic.
Exercise 22: More Practice: Running Maximum
A race display records the best score seen after each round.
Specification: Define running_max(numbers) for a nonempty list. Seed best = numbers[0]; loop through the scores, update best when a larger score appears, and append the current best each time.
Worked sample calls:
running_max([3, 7, 2, 9, 4]) -> [3, 7, 7, 9, 9]
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function running_max.
Exercise 23: More Practice: Fix the Index Error
A result printer asks for a position beyond the end of its list.
Specification: Read the broken function and exact error. Repair last_score(scores) by returning the last item with index -1; the repaired call prints 6.
def last_score(scores):
return scores[3]
print(last_score([8, 5, 6]))
IndexError: list index out of range
Worked sample calls:
last_score([8, 5, 6]) -> 6
How this is checked: Checked by tests that run your function last_score.
Exercise 24: More Practice: Fix the Missing Value
A cleanup call tries to remove a value that is absent.
Specification: Read the broken function and exact error. Repair drop_seven(numbers) by guarding numbers.remove(7) with if 7 in numbers: and returning the list; the repaired call prints [4, 5].
def drop_seven(numbers):
numbers.remove(7)
return numbers
print(drop_seven([4, 5]))
ValueError: list.remove(x): x not in list
Worked sample calls:
drop_seven([4, 5]) -> [4, 5]
How this is checked: Checked by tests that run your function drop_seven.
Exercise 25: More Practice: Fix the String Sum
A list of digit strings cannot be totaled as numbers.
Specification: Read the broken function and exact error. Repair total_of_line(line) by making an empty numbers list, appending int(part) for each split piece, then returning sum(numbers). The repaired call prints 9.
def total_of_line(line):
parts = line.split()
return sum(parts)
print(total_of_line("4 5"))
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Worked sample calls:
total_of_line("4 5") -> 9
How this is checked: Checked by tests that run your function total_of_line.
Exercise 26: More Practice: Smallest Gap
A set of measurements needs its closest neighboring values.
Specification: Define smallest_gap(numbers) for at least two values. Sort a copy with sorted. Seed the best gap from its first two items, then compare each neighboring pair by index. Return the smallest difference.
Worked sample calls:
smallest_gap([15, 3, 9, 22, 11]) -> 2
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function smallest_gap.
Exercise 27: More Practice: Is It Sorted?
A score checker asks whether a list is already in increasing order, allowing ties.
Specification: Define is_sorted(numbers). Return numbers == sorted(numbers).
Worked sample calls:
is_sorted([2, 5, 5, 9]) -> True
is_sorted([4, 1, 6]) -> False
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: Checked by tests that run your function is_sorted.
Exercise 28: More Practice: Long Words
A library display keeps words that meet a minimum length.
Specification: Define long_words(words, minimum). Return a new list containing each word with len(word) >= minimum, in its original order.
Worked sample calls:
long_words(["sled", "umbrella", "sky", "lantern"], 5) -> ['umbrella', 'lantern']
Real program
The real program reads one line of words, then the minimum length with input().
How this is checked: Checked by tests that run your function long_words.
Exercise 29: More Practice: Common Elements
Two number lists have shared members, but the first list sets the output order.
Specification: Define common(first, second). Loop over first and append each value found in second; return the new list in first-list order.
Worked sample calls:
common([3, 8, 5, 12], [5, 3, 7]) -> [3, 5]
Real program
The real program reads one line of numbers for each list with input().
How this is checked: Checked by tests that run your function common.
Exercise 30: More Practice: Class Average
A teacher needs the arithmetic mean of scores read one at a time.
Specification: Define average_of(numbers) for a nonempty list. Use a hand-written total loop, then divide by len(numbers). In the stand-in and real program print f"Average: {average}".
Worked sample calls:
average_of([12, 15, 9, 20]) -> 14.0; printed: Average: 14.0
Real program
The real program reads a count n, then n score lines with input().
How this is checked: Checked by tests that run your function average_of.
Exercise 31: Keep Approved Values
A puzzle accepts only values that appear on its approved list.
Specification: Define keep_approved(values, approved). Start with an empty result list. Loop directly over values; if a value is in approved, append it to the result. Keep repeats and preserve the original order. Return the result list.
Worked sample calls:
keep_approved([7, 2, 7, 5], [2, 5]) -> [2, 5]
keep_approved([3, 3, 8], [3, 9]) -> [3, 3]
keep_approved([4, 6], [1, 2]) -> []
Real program
The real program reads one line of values and a second line of approved values with input().
How this is checked: Checked by tests that run your function keep_approved.
Exercise 32: Longest Word Position
A word game needs the position of its longest word.
Specification: Define position_of_longest(words). The list has at least one item. Start best_position at 0. Use an index loop and compare the lengths of the words at the current and best positions. Update only for a strictly longer word, so a tie keeps the earliest position. Return best_position.
Worked sample calls:
position_of_longest(["owl", "panther", "fox"]) -> 1
position_of_longest(["kiwi", "apricot", "fig"]) -> 1
position_of_longest(["sun", "map", "key"]) -> 0
Real program
The real program reads one line of words with input().
How this is checked: Checked by tests that run your function position_of_longest.
Exercise 33: Vertical Bar Chart
A chart rises from bottom to top with dots where a column has no bar.
Specification: Define vertical_bars(values) for a nonempty list. Set top = max(values). For each i in range(top), set level = top - i; for each value append # if it reaches the level, else .. Join row strings with "\n" and return the picture.
Worked sample calls:
vertical_bars([2, 4, 1]) -> ".#.\n.#.\n##.\n###"
Real program
The real program reads one line of space-separated bar heights with input().
How this is checked: Checked by tests that run your function vertical_bars.
Exercise 34: Minesweeper Counts
A mine board marks mines with stars and all other cells with adjacent-mine counts.
Specification: Define mine_counts(board) for a list of equal-length row strings. Return a new list of row strings. For each non-mine cell inspect the eight neighboring positions; check both bounds with chained comparisons such as 0 <= r < rows, then count * neighbors. Leave each mine as *.
Worked sample calls:
mine_counts(["*..", "...", ".*."]) -> ['*10', '221', '1*1']
Real program
The real program reads a row count, then one board row per line with input().
How this is checked: Checked by tests that run your function mine_counts.
Exercise 35: Game of Life Step
A tiny board advances one generation; # is alive and . is empty.
Specification: Define life_step(board) returning a new list of row strings. Count the eight live neighbors of each cell with bounds checks. Use an if/elif chain: a live cell survives with 2 or 3 neighbors; a dead cell becomes live with exactly 3; otherwise write ..
Worked sample calls:
life_step(["...", "###", "..."]) -> ['.#.', '.#.', '.#.']
Real program
The real program reads a row count, then one board row per line with input().
How this is checked: Checked by tests that run your function life_step.
Exercise 36: Selection Sort
A sorter must find the smallest remaining item by hand.
Specification: Define selection_sort(numbers). For each position find the index of the smallest item at or after it with an inner loop. Swap through a temporary variable, then return the changed list. Do not call sort or sorted.
Worked sample calls:
selection_sort([29, 10, 14, 37, 13]) -> [10, 13, 14, 29, 37]
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: You check this one yourself, against the list below.
The site cannot check this one. Run your program, then tick each item below when your work does it.
Exercise 37: Statistics Report
One line should combine three statistics from the same data.
Specification: Define stats_report(numbers) for a nonempty list. Calculate the mean with sum(numbers) / len(numbers), call your own median(numbers) and mode(numbers) helpers from Exercises 11 and 12, and return one f-string in the form mean {mean} median {middle} mode {common}.
Worked sample calls:
stats_report([6, 2, 9, 2, 5]) -> "mean 4.8 median 5 mode 2"
Real program
The real program reads one line of space-separated numbers with input().
How this is checked: You check this one yourself, against the list below.
The site cannot check this one. Run your program, then tick each item below when your work does it.