Lists and Tuples in Python

Lists and tuples let a Python program keep many values under one name. This material shows how to create lists, read items and slices by position, change lists with methods, and process them with loops, including tables stored as lists of lists. It covers tuples and unpacking, explains why two variables can share one list and how to copy a list safely, and ends with sorting by sort(), sorted() and key functions.

BeginnerLesson 6 of 10 in Python for Beginners: Introduction to Programming

What you will learn

  1. Create lists, read single items and slices by index, and combine and summarize lists with Python's operators and built-in functions.
    • Create a list and read its items by index
      Write list literals, build lists with list(), measure them with len(), read items with positive and negative indices, and test membership with in.
    • Slice a list
      Take part of a list with start:stop:step slices, predict the result when values are omitted, negative or out of range, and tell a slice apart from a single item.
    • Combine and summarize lists with operators and built-in functions
      Join and repeat lists with + and *, compare lists, compute totals, extremes and averages with sum(), min() and max(), and convert between strings and lists.
  2. Add, insert, remove, find and replace items in a list, and use each method's effect and return value correctly.
    • Add and remove items
      Grow and shrink a list with append(), extend(), insert(), pop(), remove(), del and clear(), and tell their effects and return values apart.
    • Find, count and replace items
      Locate values with index(), count() and in, and replace single items or whole ranges by assigning to an index or a slice.
  3. Visit every item of a list with loops, apply counting, totaling, searching, filtering and transforming patterns, and work with lists of lists as tables.
    • Loop over items and positions
      Choose between looping over items, over indices with range(len()), or over both with enumerate() and zip(), and change a list safely while processing it.
    • Apply common list-processing patterns
      Total, count, find extremes, search, filter and transform the items of a list with loops, and recognize when a built-in function does the same job.
    • Work with nested lists
      Store a table as a list of rows, read and change cells with two indices, and visit every cell with nested loops.
  4. Store fixed groups of values in tuples, decide when a tuple fits better than a list, and unpack sequences into separate variables.
    • Create tuples and choose between tuples and lists
      Write tuples, including empty and one-item tuples, read them by index and slice, and explain what their immutability allows and forbids.
    • Pack and unpack values
      Assign several variables at once from a tuple or list, swap two values, collect the remaining values with a starred name, and return several values from a function.
  5. Predict how a change made through one variable shows up in others, copy lists when independence is needed, and pass lists to functions without surprises.
    • Tell names, objects and aliases apart
      Explain that variables refer to objects, recognize when two names share one list, and distinguish identity (is) from equality (==) and mutation from rebinding.
    • Copy lists and avoid shared inner lists
      Make an independent copy with slicing, list() or copy(), recognize when a shallow copy still shares nested lists, and use a deep copy when it must not.
    • Pass lists to functions and return them
      Predict when a function changes the caller's list, choose between changing a list in place and returning a new one, and avoid a mutable default argument.
  6. Put data in order with sort() and sorted(), ascending or descending, and control the order with key functions and the way tuples compare.
    • Sort with sort() and sorted()
      Choose between sorting a list in place and making a sorted copy, sort in descending order, tell reversing from sorting, and predict how numbers and strings are ordered.
    • Sort by a key and sort records
      Sort by a computed key such as length or lowercase text, sort lists of tuples by one or several fields, and use the fact that Python's sort is stable.

Python Lists and Tuples study guide

6 chapters

1

Create and read lists

A list gives a program one place to keep an ordered collection, such as scores or names. Its positions let you reach a particular item, while slices let you select a run of items or step through a pattern. Creating, reading and combining lists involves several different result types: a single item, a new list, a number or a string. Following those results makes it easier to choose the next operation and spot a boundary error.

1.1 Create a list and read a position

A list keeps values in a chosen order. Write the items between square brackets, with commas between them. Each item has a position, so repeated values still occupy separate places.

Build and measure a list
scores = [88, 92, 75]
print(scores)
print(len(scores))

Output:

[88, 92, 75]
3

len() counts items, not the largest value or the final position. Lists can contain mixed types, as in [3, "three", 3.0, True], although keeping related data together usually makes processing easier. [] and list() both create an empty list. Its length is 0, and it can grow as the program collects values.

list() can also collect the items of an iterable, an object a for loop can walk through. list(range(4)) gives [0, 1, 2, 3]. list("cat") gives ['c', 'a', 't']: the string supplies one character at a time. The result is a new list.

Count positions from zero

An index identifies one position. Python starts at 0, so the three scores have indices 0, 1 and 2.

ExpressionResultPosition
scores[0]88First
scores[1]92Second
scores[2]75Third
scores[-1]75Last
scores[-2]92Second from last
scores[-3]88Third from last

Negative indices count backward from the end. For a list of length n, the valid indices run from -n through n - 1. The last item is scores[len(scores) - 1], or more simply scores[-1]. -0 is still 0; it does not mean the last position.

Recognize an invalid index

scores[3] raises IndexError because no fourth item exists. scores[len(scores)] makes the same mistake: the count is one greater than the last nonnegative index. An empty list has no valid item index, including -1.

A list index must be an integer, not a float. scores[1.0] raises TypeError, even though 1.0 has a whole-number value. / produces a float, so scores[len(scores) / 2] also fails. With this three-item list, len(scores) // 2 produces the integer 1, and scores[1] is 92.

Ask whether a value occurs

Membership checks values, not positions:

colors = ["red", "green"]
print("green" in colors)
print("Green" in colors)
print("blue" not in colors)

Output:

True
False
True

in and not in return Boolean values and work on empty lists too. String comparisons are case-sensitive, so "Green" and "green" do not match. A membership test is useful before an operation that requires a value to be present, such as removing it or finding its position.

Key Takeaways

  • Lists preserve order and may contain repeated values.
  • len(values) counts items; the last nonnegative index is len(values) - 1.
  • Negative indices count from the end, starting at -1.
  • An invalid item index raises IndexError; a float index raises TypeError.
  • in tests whether an equal value occurs in the list.

1.2 Take a slice of a sequence

A slice selects a sequence of items and returns a new sequence. For a list, the result is another list, even when it contains only one item or no items.

Include the start and leave out the stop
letters = ["a", "b", "c", "d", "e", "f"]
print(letters[1:4])

Output:

['b', 'c', 'd']

The positions selected are 1, 2 and 3. Position 4 is the stopping boundary, so 'e' is left out. With a step of 1 and bounds satisfying 0 <= start <= stop <= len(letters), the number of selected items is stop - start. Here it is 3. letters[4:2] gives [] because a forward slice cannot reach an earlier stop.

Leave out a boundary
SliceMeaningResult
letters[:2]First two items['a', 'b']
letters[4:]From position 4 to the end['e', 'f']
letters[:]All items in a new list['a', 'b', 'c', 'd', 'e', 'f']
letters[-2:]Last two items['e', 'f']
letters[:-1]All except the last['a', 'b', 'c', 'd', 'e']

Negative bounds count from the end just as negative indices do. letters[:n] and letters[n:] divide the list at one boundary. Joining those two slices rebuilds its contents in their original order.

Control the step

The full form is values[start:stop:step]. A step of 2 selects a position, skips one and selects the next. letters[::2] gives ['a', 'c', 'e'], while letters[1::2] gives ['b', 'd', 'f'].

A negative step moves backward. letters[::-1] starts at the last item and produces ['f', 'e', 'd', 'c', 'b', 'a']. For a bounded backward slice, letters[4:1:-1] visits indices 4, 3 and 2, giving ['e', 'd', 'c']; the stop is still excluded. A step of 0 raises ValueError because it cannot move to another position.

Separate a boundary from a position

Slice bounds may extend past either end. Python cuts them back: letters[4:100] is ['e', 'f'], and letters[10:] is []. These slices do not raise IndexError. Reading the single item letters[10] does.

letters[2] is the string 'c'. letters[2:3] is the list ['c']. The colon changes the kind of result, which matters when later code expects a string or a list.

Work with the result

After first_three = letters[:3], assigning first_three[0] = "z" changes only that new outer list; letters[0] stays 'a'. A full slice is a shallow copy, so nested mutable items can still be shared.

Strings and tuples follow the same boundary and step rules. The result keeps the original sequence type: "python"[1:4] gives 'yth', and (10, 20, 30)[1:] gives (20, 30).

Key Takeaways

  • A slice includes its start and excludes its stop.
  • Omitted bounds select through the appropriate end of the sequence.
  • The step controls direction and spacing; zero is invalid.
  • Out-of-range slice bounds are clipped.
  • An item lookup returns one item; a slice returns a sequence.
  • A list slice makes a new outer list.

1.3 Combine values and calculate summaries

Lists support operators for building sequences and functions for summarizing their values. Check whether an operation creates a new list, produces a number or returns text: those results serve different jobs.

Join or repeat lists

+ joins two lists and creates a new list. [1, 2] + [3] gives [1, 2, 3] without changing either input. Both operands must be lists: [1, 2] + 3 raises TypeError. Put a single extra value in a one-item list when using +.

* repeats the sequence. [0] * 4 gives [0, 0, 0, 0], and ["ab", "cd"] * 2 gives ['ab', 'cd', 'ab', 'cd']. It repeats items, not the characters inside each string. A zero or negative repetition count gives []. counts = [0] * 7 provides seven starting counters. Repeating an inner list shares it across positions, which matters when those rows are changed later.

Total, extremes and average
ExpressionResult
sum([4, 8, 15])27
min([4, 8, 15])4
max([4, 8, 15])15
sum([])0

sum() adds numbers. It does not join strings; sum(["a", "b"]) raises TypeError. min() and max() find the smallest and largest items, so the items must support comparison with each other. All-string lists work: max(["pear", "apple"]) gives 'pear' through character-by-character ordering. An empty list has no minimum or maximum and raises ValueError for either call.

The mean is the total divided by the number of items:

temps = [18.5, 21.0, 19.5, 23.0]
if temps:
    total = sum(temps)
    mean = total / len(temps)
    print(total, mean)

Output:

82.0 20.5

The condition works because empty lists count as false and nonempty lists as true. Without the guard, averaging [] would divide by zero and raise ZeroDivisionError. Choose what the program should do when no readings exist, such as return None.

Compare sequences in order

== checks matching items in matching positions. [1, 2, 3] == [1, 2, 3] is True; [1, 2, 3] == [3, 2, 1] is False.

For < and >, compare from the left and stop at the first unequal pair. [2, 9] < [3, 0] is True because 2 is less than 3. The 9 and 0 do not decide anything. When one list is the beginning of another, the shorter one comes first: [2] < [2, 0] is True.

Move between text and lists
colors = "red,green,blue".split(",")
print(colors)
print(", ".join(["red", "green"]))

Output:

['red', 'green', 'blue']
red, green

split() divides a string at its separator. join() is called on the separator and places it between the strings supplied. Every item must be a string. To join numbers, first build a list of their str() results; passing [1, 2] directly to join() raises TypeError.

Key Takeaways

  • + joins lists; * repeats their sequence of items.
  • sum, min and max produce summary values.
  • Guard an empty list before calculating a mean or an extreme.
  • Sequence comparison uses item order and the first unequal pair.
  • split creates text pieces; a separator’s join combines strings.
2

Change a list

A shopping list grows, a queue loses its first item, and a recorded price needs a correction. Python provides list methods and assignment for these changes. The choice depends on whether you know a value or a position, whether you need one item or several, and whether you need to keep a removed item. Paying attention to a method’s return value prevents a change to the list from accidentally replacing its name with None.

2.1 Add and remove list items

Lists are mutable: a program can change their contents after creating them. A method belongs to an object and is called with a dot, as in cart.append("eggs"). Its effect on the list and its return value are two separate things.

Add one item or several
cart = ["milk"]
cart.append("eggs")
cart.extend(["tea", "jam"])
print(cart)

Output:

['milk', 'eggs', 'tea', 'jam']

append(x) adds exactly one item at the end. If x is a list, that whole list becomes one nested item. Starting with ['milk', 'eggs'], cart.append(["tea", "jam"]) produces ['milk', 'eggs', ['tea', 'jam']], of length 3.

extend(iterable) adds the items supplied by the iterable separately. Extending with ["tea", "jam"] makes the cart length 4. Extending with "ab" adds 'a' and 'b' separately; append the string to keep 'ab' as one item.

insert(i, x) adds an item before the current position i. After nums = [10, 30] and nums.insert(1, 20), the list is [10, 20, 30]. Later items shift right. insert(0, x) adds at the front; an index past the end adds at the end without an index error.

Remove by position or value
OperationUsesReturns
items.pop()Last positionRemoved item
items.pop(i)Position iRemoved item
items.remove(x)First value equal to xNone
del items[i]Position iNo return value
del items[start:stop]Slice of positionsNo return value
items.clear()Whole listNone

With nums = [10, 20, 30], last = nums.pop() saves 30 and leaves [10, 20]. nums.pop(0) then returns 10 and leaves [20]. An empty list or invalid position makes pop() raise IndexError.

remove() takes a value. With pets = ["cat", "dog", "cat"], pets.remove("cat") leaves ['dog', 'cat']. Only the first match disappears. If the value is missing, remove() raises ValueError. Use a membership check when it may be absent. To remove every 'cat', use:

while "cat" in pets:
    pets.remove("cat")

With [5, 0, 7], remove(0) removes the value 0 and leaves [5, 7]; pop(0) removes the value at position 0, giving [0, 7]. The argument's meaning determines the method.

del can delete a range: from [5, 6, 7, 8], del nums[1] leaves [5, 7, 8], and del nums[0:2] then leaves [8]. clear() leaves the existing list empty.

Keep the return value straight

append, extend, insert, remove and clear return None. Write cart.append("tea") on its own line. Writing cart = cart.append("tea") makes cart refer to None; a later cart.append("jam") raises AttributeError. Save a method result only when it provides a value the program needs, as last = cart.pop() does.

Key Takeaways

  • append adds one item; extend adds each supplied item.
  • insert adds before a position and shifts later items.
  • pop removes by position and returns the item.
  • remove deletes the first equal value and fails if it is absent.
  • del deletes positions or slices; clear empties the same list.
  • Methods such as append return None, so do not assign that result back to the list.

2.2 Find values and replace items

Finding a value, counting it and replacing it are different operations. Use a membership test when you need a yes-or-no result, a search method when you need a position, and assignment when you want the list to change.

Find the first matching position
days = ["Mon", "Tue", "Wed", "Tue"]
print(days.index("Tue"))
print(days.index("Tue", 2))
print(days.count("Tue"))
print(days.count("Sun"))

Output:

1
3
2
0

index(x) returns the first position containing a value equal to x. Its optional start argument tells Python where to begin searching. days.index("Tue", 2) skips the match at position 1 and finds the one at position 3. The answer remains an index into the whole list, not a count from the new starting point.

index() raises ValueError when the value is absent. Lists have no find() method that returns -1. If a missing value is expected, test membership first:

if "Sun" in days:
    position = days.index("Sun")
    print(position)

This code prints nothing because 'Sun' is absent. count(x) can be used without that guard: it returns 0 when there are no matches. These operations use equality, so [1, 2.0].count(2) is 1. Text still respects case: 'tue' does not equal 'Tue'.

Replace one existing item
prices = [4.5, 3.0, 7.25]
prices[1] = 3.5
print(prices)

Output:

[4.5, 3.5, 7.25]

The old second value is overwritten and the length stays 3. The index must exist: prices[3] = 1.0 raises IndexError. To add at the end, use append().

StatementEffect on [10, 20]
nums[0] = 99[99, 20]
nums.insert(0, 99)[99, 10, 20]

Replacement uses an existing slot. Insertion creates an extra slot before the selected position.

Replace a range with slice assignment
nums = [1, 2, 3, 4, 5]
nums[1:3] = [20, 30, 40]
print(nums)
nums[0:2] = []
print(nums)

Output:

[1, 20, 30, 40, 4, 5]
[30, 40, 4, 5]

The first assignment replaces the two items at indices 1 and 2 with three new items, growing the list by one. An ordinary contiguous slice can be replaced with a shorter or longer sequence. Assigning [] deletes the selected range. This changes the original list; it is different from reading a slice into a new variable.

Edit text by building new text

A string is immutable, so word = "cat" followed by word[0] = "b" raises TypeError. Build a new string with word = "b" + word[1:], or make a list of characters, change it and join it:

letters = list("cat")
letters[0] = "b"
word = "".join(letters)
print(word)

Output:

bat

Key Takeaways

  • index returns the first matching position and raises ValueError for a missing value.
  • count returns the number of equal items, including zero.
  • Item assignment replaces a slot that already exists.
  • Contiguous slice assignment can change the length of a list.
  • Strings must be rebuilt instead of changed by item assignment.
3

Process lists with loops

Loops turn a stored collection into useful results: a total, a matching position, a filtered list or a changed table. Each task starts by choosing what to carry through the loop and which information the loop needs from each item. Some tasks need only values, others need positions or paired records. Nested lists add one more level to follow, so processing a table means working through its rows and then its cells.

3.1 Walk through items and positions

A loop can use a list's values, its positions or both. Pick the form that supplies what the loop body needs. For a change to the list, also check whether the statement changes an item or only rebinds a local name.

Use items directly
for name in ["Ana", "Ben"]:
    print("Hi", name)

Output:

Hi Ana
Hi Ben

The loop visits each item in order. On each pass, name refers to the current item. Assigning a different value to name does not replace that item in the list. In for r in readings: r = 0, only the name r changes.

Use positions to replace items
readings = [3, -1, 4, -5]
for i in range(len(readings)):
    if readings[i] < 0:
        readings[i] = 0
print(readings)

Output:

[3, 0, 4, 0]

range(len(readings)) supplies 0, 1, 2 and 3. At index 1, the condition is true, so item assignment replaces -1. At index 3, it replaces -5. Positive readings keep their values. Using range(len(readings) + 1) would also reach index 4, which does not exist.

Obtain a position and an item together

enumerate() supplies pairs. Unpack each pair in the loop header:

for i, name in enumerate(["Ana", "Ben"]):
    print(i, name)

Output:

0 Ana
1 Ben

enumerate(names, start=1) supplies labels starting at 1 for a numbered display. Those labels are no longer the list's zero-based indices. To visit from last to first without changing the list, use for item in reversed(names):. For backward indices, use range(len(names) - 1, -1, -1); a three-item list gives 2, 1, 0.

Pair two lists
names = ["Ana", "Ben"]
scores = [90, 85]
for name, score in zip(names, scores):
    print(name, score)

Output:

Ana 90
Ben 85

zip() pairs items at matching positions and stops at the shorter input. If every record matters, check the lengths before relying on it; an unmatched final name will otherwise be skipped.

Control an index with while

A while loop needs a starting index, a boundary check and a step:

i = 0
while i < len(readings):
    print(readings[i])
    i += 1

Forgetting the increment prevents this loop from finishing. Using <= reaches len(readings) and causes IndexError.

Avoid shifting items during a for loop

Removing items changes the positions of those that follow. With [1, 2, 2, 3], removing each encountered 2 while looping over that same list leaves [1, 2, 3]: the second 2 shifts into the position just visited. Loop over nums[:] if removals must affect the original, or build a new list of items to keep. Adding items to the list being visited can also make the loop behave unexpectedly.

Key Takeaways

  • Use a direct loop for items, range(len(...)) for positions, and enumerate for both.
  • Rebinding the loop variable does not replace a list item.
  • zip stops at the shorter input.
  • reversed visits backward without changing the list.
  • A while loop must advance its index and stop before len(values).
  • Build a new list or loop over a copy when removing items.

3.2 Build totals, searches and new lists

Many list problems use a few reusable loop patterns. Decide what result the program needs, set up that result before the loop and update it as each item arrives.

Accumulate a total or a count
sales = [120, 75, 205, 50]
total = 0
for sale in sales:
    total += sale
print(total)

Output:

450

The running total becomes 120, 195, 400 and 450. Setting total = 0 inside the loop would erase previous work on every pass. sum(sales) performs this total directly.

A counter adds 1 for each qualifying item, not the item's value:

scores = [72, 45, 60, 88, 59]
passed = 0
for score in scores:
    if score >= 60:
        passed += 1
print(passed)

The output is 3: 72, 60 and 88 qualify. > 60 would give 2 because it excludes exactly 60. Keep the threshold's wording and comparison in agreement.

Find an extreme

For a nonempty list, initialize a running maximum from a real item:

temps = [-3, -8, -1, -5]
highest = temps[0]
for temp in temps[1:]:
    if temp > highest:
        highest = temp
print(highest)

Output is -1. Starting at 0 would wrongly keep 0 because all readings are lower. Use < to find the minimum, or use the built-ins min() and max(). Check for an empty list before accessing its first item.

Stop at the first match
values = [4, 0, -2, 5, -7]
position = -1
for i, value in enumerate(values):
    if value < 0:
        position = i
        break
print(position)

The output is 2. -1 is a chosen signal for no match; do not use it as an index unless the search succeeded, because it is also a valid last-item index. break preserves the first matching position. Without it, later matches would overwrite the result.

x in values tests for one exact value, and values.index(x) finds its first position. A condition such as “is negative” needs a condition-based search like the loop above.

Filter or transform

A filter keeps selected original items:

passing = []
for score in scores:
    if score >= 60:
        passing.append(score)
print(passing)

Output is [72, 60, 88]; scores keeps all five items. A transformation computes one new item from each original:

nums = []
for text in ["3", "14", "15"]:
    nums.append(int(text))
print(nums, sum(nums))

Output is [3, 14, 15] 32. The conversion happens before addition; summing the original strings fails.

Return a reusable result
def average(values):
    if not values:
        return None
    return sum(values) / len(values)

average([18.5, 21.0, 19.5, 23.0]) returns 20.5. The empty case returns None without dividing by zero, and the function leaves the input list unchanged.

Key Takeaways

  • Initialize an accumulator before the loop.
  • A counter adds 1 per match; a total adds values.
  • Start a running extreme from an actual item.
  • Use break to keep the first match in a search.
  • Filtering selects items; transforming computes new values.
  • A returning function lets the caller keep a result without changing the input.

3.3 Read and process a table of rows

A nested list is a list that contains other lists. A table commonly uses one inner list per row. Each lookup selects one level, so reading a cell takes two indices.

Select the row, then the cell
grid = [[1, 2, 3], [4, 5, 6]]
print(grid[1])
print(grid[1][2])
print(len(grid), len(grid[0]))

Output:

[4, 5, 6]
6
2 3

grid[1] selects the second row; [2] then selects that row's third item. len(grid) counts rows, while len(grid[0]) counts cells in the first row. This rectangular table has six cells. grid[2][1] fails at the first lookup because row 2 does not exist. Swapping row and column positions can select the wrong cell or raise IndexError.

Change a cell or a whole row

grid[0][1] = 20 changes the second cell in the first row, giving [[1, 20, 3], [4, 5, 6]]. grid[0] = [0, 0, 0] replaces the entire first row. The number of lookups shows which level is being replaced.

Visit every value
grid = [[1, 2, 3], [4, 5, 6]]
total = 0
for row in grid:
    for value in row:
        total += value
print(total)

Output:

21

The inner loop completes the first row before the outer loop supplies the second row. It adds 1, 2, 3, then 4, 5, 6. A column total uses one fixed position from each row:

column_total = 0
for row in grid:
    column_total += row[1]
print(column_total)

The output is 7, from 2 and 5. This code requires each row to have a second item.

Rows do not have to be equally long. [[1], [2, 3]] is a valid nested list. Direct nested loops still visit every value because each inner loop follows its own row. Assuming all rows have len(grid[0]) items would miss values here. To count cells in such a table, add len(row) for every row.

Build independent rows
table = []
for r in range(3):
    table.append([0] * 4)
table[0][0] = 1
print(table)

Output:

[[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Each pass creates a new four-item list. The shortcut [[0] * 4] * 3 repeats a reference to one row; changing its first cell would appear in all three rows.

Store records

A row may describe one record instead of a row of numbers. With students = [["Ana", 90], ["Ben", 85]], students[1][0] is 'Ben' and students[1][1] is 85. When every record has two items, for name, score in students: unpacks them into useful names. Lists of tuples can represent the same kind of records.

Key Takeaways

  • Two indices select a row and then a cell within that row.
  • len(grid) counts rows; row lengths may differ.
  • Nested loops process each row with its own inner loop.
  • A column lookup requires that position to exist in every selected row.
  • Create each mutable row separately to avoid shared cells.
4

Use tuples and unpacking

Fixed groups of values often have meaningful positions: a point has coordinates, and a result record has a name and score. Tuples keep those positions fixed, while unpacking gives each value a useful name. These tools also explain how one assignment can swap two values and how a function can return several results. An immutable outer tuple can still contain a changeable list, so follow both the container and the objects inside it.

4.1 Choose a list or a tuple

A tuple stores items in order, like a list, but its positions cannot be replaced, added or removed. This is immutability. Tuples suit fixed groups such as coordinates, dates and records; lists suit collections that grow or change.

Create and read a tuple
point = (3, 4)
date = (2024, 7, 15)
print(date[0])
print(date[1:])
print(len(date))

Output:

2024
(7, 15)
3

Tuple indexing, negative indices, slicing and membership follow the same rules as lists. A tuple slice returns a tuple. You can loop through a tuple or use +, *, min, max, sum, count and index when its items suit the operation.

The comma creates a nonempty tuple. t = 3, 4 makes (3, 4) even without parentheses. A one-item tuple needs a trailing comma:

ExpressionValue and type
(5)Integer 5
(5,)One-item tuple (5,)
()Empty tuple
tuple([1, 2])Tuple (1, 2)
tuple("ab")Tuple ('a', 'b')

list(t) converts a tuple's items into a changeable list.

Understand what cannot change

point[0] = 5 raises TypeError because a tuple does not support item assignment. Tuples have no append, remove or sort methods; point.append(5) raises AttributeError.

A name can still be rebound to a new tuple:

point = (3, 4)
point = (5,) + point[1:]
print(point)

Output is (5, 4). The expression makes a new tuple; it does not edit the old one.

A tuple can hold a mutable item
t = ([1, 2], "x")
t[0].append(3)
print(t)

Output:

([1, 2, 3], 'x')

The first position still holds the same list. That list's contents changed. t[0] = [9] would replace the object in the position and is forbidden. Immutability of the outer tuple does not freeze an inner list.

Match the structure to its job

Use (x, y) for a coordinate, (255, 128, 0) for an RGB color or ("Ana", 90) for a two-field record. Each position has a particular meaning. Use a list for all the class's scores or a cart's items, which may grow and be reordered. A list of tuples, such as [("Ana", 90), ("Ben", 85)], combines a changeable collection with fixed record positions.

A tuple of numbers or strings can serve as a dictionary key, as in {(0, 0): "origin"}. Keys must be hashable, meaning they support Python's stable key lookup rules. A list is not hashable, and a tuple containing a list is not hashable either.

Compare tuples

Comparison starts on the left and stops at the first unequal pair. (1, 2, 5) < (1, 3, 0) is True: the first values tie, and 2 is less than 3. This same rule orders a list of tuple records when no key function is supplied.

Key Takeaways

  • A tuple has fixed item positions but may contain a mutable object.
  • The comma makes a nonempty tuple; (5,) has one item.
  • Tuple reading operations follow sequence rules.
  • Rebinding a tuple name creates a different value without editing the old tuple.
  • Tuples used as dictionary keys need hashable contents.
  • Tuple comparison uses the first unequal pair of items.

4.2 Unpack records into names

Packing gathers values into a tuple. Unpacking assigns an iterable's items to names in order. Together they let code give clear names to the fields of a record and receive several results from one function.

Match names to values
record = "Ana", 34, "Lima"
name, age, city = record
print(name, age, city)

Output:

Ana 34 Lima

The first item becomes name, the second age and the third city. Unpacking also works on lists and strings: first, second = [10, 20] and a, b, c = "xyz" assign their items in order. user, domain = "ana@example.com".split("@") gives 'ana' and 'example.com' because the split produces two pieces.

Without a starred name, the counts must match exactly. x, y = (1, 2, 3) raises ValueError for too many values; x, y, z = (1, 2) raises ValueError for not enough. Python does not silently discard extra items.

Swap values safely
a = 1
b = 2
a, b = b, a
print(a, b)

Output is 2 1. Python evaluates the entire right side using the old values before assigning either name on the left. The two-statement attempt a = b followed by b = a loses the old value of a and makes both names 2.

Collect the remaining items

A starred name receives a list of the leftover values:

first, *rest = [5, 6, 7, 8]
print(first, rest)
*init, last = [5, 6, 7, 8]
print(init, last)

Output:

5 [6, 7, 8]
[5, 6, 7] 8

The star can also occur between unstarred names: first, *middle, last = (5, 6, 7, 8) gives middle the list [6, 7]. The collected object is always a list, even when unpacking a tuple. head, *rest = [5] leaves rest as []. There must be enough items for the unstarred names, and only one starred name is allowed in the same unpacking pattern.

Unpack during a loop
for name, score in [("Ana", 90), ("Ben", 85)]:
    print(name, score)

Output:

Ana 90
Ben 85

The header unpacks each record as it arrives. This is also how for i, item in enumerate(values): and for a, b in zip(left, right): work: each iteration supplies a pair.

Return several results
def min_max(values):
    return min(values), max(values)

low, high = min_max([7, 2, 9])
result = min_max([7, 2, 9])
print(low, high)
print(result)

Output:

2 9
(2, 9)

The function returns one tuple. The caller can unpack it or retain the whole object. An underscore conventionally names a value the code does not need: _, month, day = (2024, 7, 15) keeps the month and day under descriptive names. _ remains an ordinary variable, not a special discard operation.

Key Takeaways

  • Packing collects values; unpacking assigns them in order.
  • Unstarred names require an exact item count.
  • A starred name receives a list of leftovers, possibly empty.
  • Swap with a, b = b, a to preserve both old values.
  • Multiple returned values are commonly packed into one tuple.
5

Track sharing and make copies

Two names can refer to one list, and a copied outer list can still share its rows. These relationships explain why an edit sometimes appears in more than one place. Trace which object a name reaches before deciding whether an operation mutates that object or rebinds the name. The same reasoning applies when a function receives a list and when a default argument is reused across calls. Copying provides independence at the levels that need it.

5.1 Track names that share one list

A variable is a name that refers to an object. Assignment changes what a name refers to; it does not automatically copy the object. With a mutable list, two names can therefore observe the same changes.

Follow the references
a = [1, 2, 3]
b = a
b.append(4)
print(a)
print(b)

Output:

[1, 2, 3, 4]
[1, 2, 3, 4]

There is one list and two names for it. b is an alias of a. The append changes the shared object, so reading it through either name shows the added item. Draw two arrows, one from each name, to the same list when tracing this code.

Separate equality from identity
a = [1, 2]
b = a
c = [1, 2]
print(a == b, a == c)
print(a is b, a is c)

Output:

True True
True False

== compares contents; is tests whether the objects are the same object. c has equal contents but is a separate list. id(x) gives an object's identity number, so id(a) == id(b) agrees with a is b. Identity numbers do not tell you which items a list contains.

Use == when asking whether contents match. Use is when checking sharing or a special object such as None. A fresh list literal creates a separate list, so a is [1, 2] is false for an existing list a, even if its contents match.

Mutation and rebinding have different reach
StatementWhat changes?What does an alias see?
b.append(4)Existing listAdded item
b[0] = 9Existing listReplaced item
b = [7, 8]The name bOriginal list unchanged

After the last statement, b points at a new list. a continues to refer to the original object. Rebinding one name does not redirect every name that once referred to that object.

Trace += and + separately

For lists, += extends the existing list:

a = [1]
b = a
a += [2]
print(a, b)

Output is [1, 2] [1, 2]. In contrast:

a = [1]
b = a
a = a + [2]
print(a, b)

Output is [1, 2] [1]. + creates a new list, and assignment makes a refer to it. b still refers to the original one-item list.

Look for less visible aliases

row = [0, 0] followed by table = [row, row] stores the same row twice. table[0][0] = 5 produces [[5, 0], [5, 0]] because both positions reach the same inner list.

Numbers and strings cannot change in place. After x = 5, y = x, x += 1, y stays 5; x has been rebound. A tuple's item positions also stay fixed, but an inner list can change. After t = ([1], 2), u = t and t[0].append(3), u shows ([1, 3], 2): both names still reach the same tuple and its same mutable list.

Key Takeaways

  • Assignment shares a reference; it does not copy a list.
  • == compares values, while is checks object identity.
  • Mutation is visible through aliases; rebinding redirects one name.
  • For lists, += mutates while + creates a new list.
  • Sharing can occur inside a table or tuple as well as between variable names.

5.2 Copy the levels that need independence

Copying creates a new object, but the depth of that copy matters. A new outer list can still hold references to the original inner lists.

Make a new outer list
a = [1, 2, 3]
b = a.copy()
b.append(4)
print(a)
print(b)
print(a is b)

Output:

[1, 2, 3]
[1, 2, 3, 4]
False

a[:], list(a) and a.copy() all make a shallow copy of a list. Its outer container is new, and its item references are copied. With immutable numbers or strings, replacing or adding an item in one outer list leaves the other alone.

See what a shallow copy shares
a = [[1, 2], [3, 4]]
b = a.copy()
b[0].append(99)
print(a)
print(b is a, b[0] is a[0])

Output:

[[1, 2, 99], [3, 4]]
False True

The two outer lists differ, but their first items refer to the same inner list. append() changes that inner object.

Replacing a position in b is different. After b[1] = [0], b has a different second row while a[1] remains [3, 4]. Assignment changes one reference in b's outer list; it does not mutate the old second row.

Copy nested lists too
import copy

a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)
b[0].append(99)
print(a)
print(b)

Output:

[[1, 2], [3, 4]]
[[1, 2, 99], [3, 4]]

import copy makes the copying module available. copy.deepcopy() recursively copies the nested list structure, so edits to copied inner lists do not reach the original. Use it when changes at those inner levels must be independent. A shallow copy is enough if only the outer list's order or item references will change.

Avoid repeated references when building rows
table = [[0] * 3] * 2
table[0][0] = 7
print(table)

Output is [[7, 0, 0], [7, 0, 0]]. Multiplication repeated the reference to one row. It did not construct two rows.

Build each row inside the loop:

table = []
for r in range(2):
    table.append([0] * 3)
table[0][0] = 7
print(table)

Output is [[7, 0, 0], [0, 0, 0]]. [0] * 3 itself is safe for independent counters: integers cannot be mutated, and item assignment replaces just one position.

Choose a copy for a reason

Preserving the original order before sorting requires a new outer list. Preserving original nested measurements while changing copied cells requires independent inner lists too. Read-only processing needs no copy, and intentional shared editing can use aliases. To investigate a nested bug, check both b is a and b[0] is a[0]; testing only the outer lists misses inner sharing.

Key Takeaways

  • Slicing, list() and copy() make a new outer list.
  • A shallow copy retains references to the original items.
  • Replacing a copied row differs from mutating a shared row.
  • copy.deepcopy copies nested lists recursively.
  • Nested list multiplication repeats references to one row.
  • Copy only the levels whose changes need to be independent.

5.3 Make a function’s list effects clear

A function parameter is another name for the object supplied by the caller. A list argument is not automatically copied. The function can mutate that object, rebind its local parameter or return a new result; these actions affect the caller in different ways.

Mutation reaches the caller
def add_bonus(scores):
    scores.append(5)

marks = [80]
result = add_bonus(marks)
print(marks)
print(result)

Output:

[80, 5]
None

scores and marks initially refer to the same list. Appending through scores changes it. Because the function has no explicit return statement, its result is None.

By contrast, def reset(scores): scores = [] rebinds only the local parameter. The caller's marks still refers to its old list. Use scores.clear() to empty that actual shared list.

Keep a returned list when needed

Two common designs are changing a list in place and returning None, or leaving it alone and returning a new list:

def drop_first(values):
    del values[0]

def tail(values):
    return values[1:]

For nums = [1, 2, 3], calling drop_first(nums) leaves nums as [2, 3]. Writing nums = drop_first(nums) would instead bind nums to None. Starting again from [1, 2, 3], shorter = tail(nums) gives shorter the list [2, 3] while nums stays unchanged. Calling tail(nums) without keeping its result discards the new list.

Other designs are useful too: sum() returns a summary, and pop() both changes a list and returns an item. Make the effect and return value clear in a function's name or docstring.

Build a result without changing the input
def without_negatives(values):
    kept = []
    for value in values:
        if value >= 0:
            kept.append(value)
    return kept

original = [3, -2, 0, 7]
print(without_negatives(original))
print(original)

Output:

[3, 0, 7]
[3, -2, 0, 7]

A caller can also protect its outer list by passing a shallow copy, such as drop_first(original[:]). An operation that edits inner lists would need copying at those levels too.

Avoid a shared mutable default
def add_item(item, basket=[]):
    basket.append(item)
    return basket

The default list is created when the def statement runs, once. add_item("a") returns ['a'], and the next default call add_item("b") returns ['a', 'b']. Use None to request a fresh list:

def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    return basket

Each call without a basket now creates its own list. Passing an existing basket still allows intentional shared changes. A function cannot mutate a number or string, or replace a tuple's positions, but it can mutate a list stored in a tuple, such as by calling pair[0].append(9).

Key Takeaways

  • A parameter initially refers to the caller’s object.
  • Mutating a list parameter changes that object; rebinding the parameter does not.
  • Keep a newly returned list if the program needs it.
  • Check both a function’s effect and its return value.
  • A mutable default list is shared across default calls.
  • Use None and create a list inside the function for a fresh default.
6

Put sequences in order

Putting records in order requires two choices: which values decide the order, and whether the original collection should change. Python can sort a list in place or return a new list from any iterable. Key functions let a program compare one field, a computed value or several fields in sequence. Equal keys preserve their input order, which makes ties predictable and supports sorting by more than one rule.

6.1 Choose how to sort or reverse data

Sorting puts items in comparison order. Reversing flips their current order. Also decide whether the program should change the existing list or keep it and receive a new list.

Sort in place or keep a new list
nums = [3, 1, 2]
new = sorted(nums)
print(nums)
print(new)
nums.sort()
print(nums)

Output:

[3, 1, 2]
[1, 2, 3]
[1, 2, 3]

sorted() creates a new list. sort() is a list method that rearranges the existing list and returns None. nums = nums.sort() loses the name's reference to the list and binds it to None. Write nums.sort() on its own line or use nums = sorted(nums). print(nums.sort()) prints None even though the list has been reordered.

sorted() accepts any iterable and always returns a list. sorted((3, 1, 2)) gives [1, 2, 3], and sorted("cab") gives ['a', 'b', 'c']. Strings and tuples have no in-place sort() method.

Descending order and reversed order
Expression for nums = [3, 1, 2]ResultChanges nums?
sorted(nums, reverse=True)[3, 2, 1]No
nums.sort(reverse=True)Returns None; list becomes [3, 2, 1]Yes
nums[::-1][2, 1, 3]No
list(reversed(nums))[2, 1, 3]No
nums.reverse()Returns None; list becomes [2, 1, 3]Yes

Each row starts from the original list. reverse=True requests descending comparison order and must be given by name; sorted(nums, True) raises TypeError. Reversing simply visits the existing positions backward, so it does not necessarily produce descending values.

Check the values being compared

Numbers sort by numerical value, including mixed integers and floats: sorted([2.5, -1, 2]) gives [-1, 2, 2.5].

Text is compared character by character. sorted(["10", "9", "100"]) gives ['10', '100', '9']. The first character '1' sorts before '9', and a string prefix comes before a longer string beginning with it. Convert numeric strings with int() or float() when numerical ordering is wanted.

The capital letters A–Z sort before the lowercase letters a–z. sorted(["b", "B", "a"]) gives ['B', 'a', 'b']. Default string order is based on character codes; it is not a case-insensitive dictionary order.

All items compared must support < with one another. sorted([3, "two", 1]) raises TypeError. Clean or convert the data before sorting.

Use sorted positions

For an odd number of scores, sorting makes the middle value easy to read:

scores = [72, 95, 64, 88, 79]
ordered = sorted(scores)
median = ordered[len(ordered) // 2]
print(ordered)
print(median)

Output is [64, 72, 79, 88, 95] followed by 79. The original list still records the order the scores arrived. This single-middle-item calculation applies to odd-length nonempty lists.

Key Takeaways

  • sort mutates a list and returns None; sorted returns a new list.
  • sorted accepts iterables such as tuples and strings.
  • reverse=True sorts descending; reversing alone flips current positions.
  • Numeric strings use text order unless converted.
  • Items must support comparison with one another.

6.2 Sort records by the fields that matter

A key function computes the comparison value for each item. The original items remain intact in the sorted result. This lets a program sort text by length or records by a selected field.

Pass a function, not a function call
words = ["kiwi", "fig", "banana"]
print(sorted(words, key=len))

Output:

['fig', 'kiwi', 'banana']

Python calls len once for each item and compares the resulting lengths, 4, 3 and 6. Pass key=len, without parentheses. key=len() tries to call len immediately with no argument and fails.

For lowercase comparison, use key=str.lower. With ["banana", "apple", "Cherry"], the default order is ['Cherry', 'apple', 'banana']. With key=str.lower, the result is ['apple', 'banana', 'Cherry']. The original capital C remains in the result; only the comparison keys are lowercase.

Select a record field
results = [("Ana", 90), ("Ben", 72), ("Cy", 85)]

def by_score(record):
    return record[1]

print(sorted(results, key=by_score))

Output:

[('Ben', 72), ('Cy', 85), ('Ana', 90)]

The function receives one record at a time. record[1] selects its score. Add reverse=True to put the highest score first. results.sort(key=by_score, reverse=True) uses the same rule but changes results itself.

key=by_score(results) is different: it calls the function on the whole list and passes its result as the key argument. Here that result is the tuple ('Ben', 72), which cannot be called as a function, so sorting raises TypeError.

Use several fields

Without a key, tuples compare their first items, then their second items to break first-item ties. Sorting [("Ben", 72), ("Ana", 90), ("Ana", 85)] gives [('Ana', 85), ('Ana', 90), ('Ben', 72)].

A key can return a tuple to choose a different field order:

def rank_key(record):
    return (-record[1], record[0])

results = [("Dee", 85), ("Ana", 90), ("Cy", 85)]
print(sorted(results, key=rank_key))

Output:

[('Ana', 90), ('Cy', 85), ('Dee', 85)]

Negating the score makes larger scores have smaller keys. Names then break score ties in ascending order. reverse=True on a positive (score, name) key would reverse both fields, including the names, so it would not meet this mixed-direction rule.

Keep equal-key items in order

Python's sorting is stable: items with equal keys keep their input order. Sorting ["bb", "a", "cc", "d"] by len gives ['a', 'd', 'bb', 'cc']. The tie between the two one-letter words keeps 'a' first; the two-letter tie keeps 'bb' first. Stability also permits sorting by a secondary field first, then by the main field.

min() and max() accept key functions too. max(words, key=len) returns 'banana', not its length. When keys tie, these functions return the first matching item encountered.

Key Takeaways

  • A key function maps one item to its comparison value.
  • Pass the function itself, such as key=len or key=by_score.
  • Key results control ordering without replacing the original items.
  • A tuple key orders by its first field, then uses later fields to break ties.
  • Negating a numeric key can reverse just that field’s direction.
  • Stable sorting preserves input order among equal keys.
  • min and max return original items and choose the first on a key tie.

Python Lists and Tuples examples

6 Walkthroughs

1

Read a week of delivery counts

13 steps
Create a list, select days and compute a safe average.
  1. 1
    IntroductionKeep the counts in order

    A delivery log stores one count per day. A list keeps the order, so a position identifies a day and a slice selects several days. You can then calculate a total or average from the selected values.

    Work with deliveries = [12, 7, 15, 9, 17]. These are five daily counts in arrival order. First track the positions, then the slice boundaries, and finally the type of result each operation produces.

  2. 2
    ExampleMatch counts to positions

    The five counts occupy indices 0 through 4:

    deliveries = [12, 7, 15, 9, 17]
    print(deliveries[0], deliveries[4])
    

    Output is 12 17. len(deliveries) is 5, but index 5 does not exist. A count tells you how many positions are present; it does not name the last one. The final count can also be read as deliveries[-1], using a negative index from the end.

  3. 3
    TipCheck a reading before using it

    Membership answers a different question from indexing:

    print(9 in deliveries)
    print(4 in deliveries)
    

    Output is True then False. The value 9 occurs, but 4 does not, even though 4 is a valid index. in checks the stored values. If you want the count at position 4, use deliveries[4], which returns 17.

  4. 4
    ChallengeFind the second-to-last count

    What does deliveries[-2] return, and would deliveries[len(deliveries)] work?

    ---reveal---

    The negative index -2 selects 9, one place before the final item 17. The second expression tries index 5 and raises IndexError. Use len(deliveries) - 1 or -1 to select the last item; the number of items is one past the final nonnegative index.

  5. 5
    ExampleSelect the middle three days

    Use index 1 as the start and index 4 as the excluded stop:

    middle = deliveries[1:4]
    print(middle)
    

    Output is [7, 15, 9]. Read the selected positions as 1, 2 and 3. Position 4 contains 17, but it marks the stopping boundary here. middle is a new list, so changing its outer positions will not replace a position in deliveries.

  6. 6
    ExplanationLeave out a boundary

    deliveries[:2] gives [12, 7], the first two days. deliveries[2:] gives [15, 9, 17], all remaining days. Both slices meet at boundary 2, so joining them rebuilds the original contents.

    deliveries[-2:] gives [9, 17]. A negative bound counts from the end. deliveries[20:] is []: an out-of-range slice boundary is clipped, unlike an out-of-range item lookup.

  7. 7
    ExampleStep through alternate days

    A third slice field controls spacing:

    print(deliveries[::2])
    print(deliveries[::-1])
    

    Output is [12, 15, 17] then [17, 9, 15, 7, 12]. Step 2 visits indices 0, 2 and 4. Step -1 visits every item backward. Both results are new lists. A zero step cannot advance and raises ValueError.

  8. 8
    ChallengeDistinguish a count from a list

    What are the values and types of deliveries[2] and deliveries[2:3]?

    ---reveal---

    deliveries[2] is the integer 15. deliveries[2:3] is the list [15]. The slice selects one position but still returns a list. This difference matters if the next operation expects a numeric count: adding 1 to the integer works, while adding 1 directly to the list raises TypeError.

  9. 9
    ExampleCalculate an average from the slice

    The middle slice is [7, 15, 9]. Add its items and divide by its length:

    total = sum(middle)
    mean = total / len(middle)
    print(total)
    print(mean)
    

    Output is 31 then 10.333333333333334. The total is 7 + 15 + 9, and the divisor is 3. / produces a floating-point result, so this average is displayed with a decimal approximation.

  10. 10
    Key InsightHandle a selection with no days

    A slice may be empty, so an average needs a guard:

    selected = deliveries[20:]
    if selected:
        print(sum(selected) / len(selected))
    else:
        print("No days selected")
    

    This prints No days selected. Empty lists count as false. Although sum([]) is 0, dividing that total by len([]) would divide by zero. min and max also fail on these empty inputs.

  11. 11
    ConnectionBuild a display line

    A display needs strings, not a list of integers:

    pieces = []
    for count in deliveries:
        pieces.append(str(count))
    print(", ".join(pieces))
    

    Output is 12, 7, 15, 9, 17. join is called on the separator and places it between items. Passing the numeric list directly would fail because every joined item must be a string. split goes the other way, dividing text into string pieces.

  12. 12
    ChallengeSelect, total and keep the original

    What does this code print?

    selected = deliveries[-3:]
    selected[0] = 0
    print(sum(selected), deliveries[2])
    

    ---reveal---

    It prints 26 15. The slice begins as [15, 9, 17], then its first position is replaced, making [0, 9, 17]. Those values total 26. The outer slice is separate, so the original count at deliveries[2] stays 15.

  13. 13
    RecapChoose the result you need

    Read one position for a single count, use a slice for a sequence, and use summary functions for totals or extremes. A list slice creates a new outer list.

    Before averaging a selection, handle its empty case. When building display text, convert numeric values to strings before joining them.

2

Edit a supply request

10 steps
Add, remove, find and replace items while tracking method results.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionFollow the list and the returned value
  2. 2
    ExampleAdd a batch of items
  3. 3
    ExamplePut one item at the front
  4. 4
    ExampleRemove and save a collected item
  5. 5
    ChallengeChoose a removal by value
  6. 6
    ExampleFind a correction’s position
  7. 7
    ExampleReplace one item with a batch
  8. 8
    ChallengeDelete a range and find a value
  9. 9
    ChallengeFinish the request without losing it
  10. 10
    RecapMatch the change to the operation
3

Clean readings and total a table

13 steps
Choose loop forms, build a result and process rows of different lengths.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionDecide what each loop carries
  2. 2
    ExplanationRead a value without editing its position
  3. 3
    ExampleReplace invalid readings by index
  4. 4
    ConnectionPair labels with readings
  5. 5
    ChallengeExplain a skipped item
  6. 6
    ExampleCount the positive readings
  7. 7
    ExampleBuild a filtered and transformed result
  8. 8
    TipSearch until the first match
  9. 9
    ChallengeChoose a valid maximum
  10. 10
    ExampleSelect a row and a cell
  11. 11
    ExampleTotal all rows
  12. 12
    ChallengeFilter across the whole table
  13. 13
    RecapKeep setup separate from repeated work
4

Use a fixed record and unpack its fields

10 steps
Follow tuple positions, starred unpacking, swaps and returned pairs.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionKeep a record together
  2. 2
    ExampleCreate the station record
  3. 3
    Key InsightTest the immutability boundary
  4. 4
    ChallengeMake a one-item tuple
  5. 5
    ExampleGive each field a name
  6. 6
    ExampleKeep the first reading and the rest
  7. 7
    ChallengeSwap coordinate values
  8. 8
    ExampleReturn a pair of extremes
  9. 9
    ChallengeRead and unpack one selected field
  10. 10
    RecapRead structure before unpacking
5

Trace a copied table through a function

14 steps
Separate aliases, shallow copies, deep copies and local parameter changes.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionDraw paths to objects
  2. 2
    ExampleCreate an alias
  3. 3
    ExampleRedirect one name
  4. 4
    ChallengePredict two kinds of addition
  5. 5
    ExampleCopy the outer table
  6. 6
    ExampleMutate a shared row
  7. 7
    Key InsightReplace a copied row
  8. 8
    ChallengeChoose a deeper copy
  9. 9
    ExampleMutate through a parameter
  10. 10
    ConnectionReturn a separate list
  11. 11
    ExplanationAvoid a persistent default basket
  12. 12
    ChallengeSeparate local rebinding from clearing
  13. 13
    ChallengeTrace a shallow copy passed to a function
  14. 14
    RecapTrace the level being changed
6

Rank records without losing their arrival order

13 steps
Sort a copy, select keys, break ties and keep equal-key order.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionSeparate stored data from comparison keys
  2. 2
    ExampleKeep the arrival order
  3. 3
    ExampleCompare reversal with descending sorting
  4. 4
    TipCheck the input type
  5. 5
    ChallengeFollow a sort result
  6. 6
    ExampleChoose a score key
  7. 7
    Key InsightKeep tied records in arrival order
  8. 8
    ChallengePass a callable
  9. 9
    ExampleAdd an alphabetical tie-breaker
  10. 10
    TipReverse only the numeric direction
  11. 11
    ConnectionPick an item by an extreme key
  12. 12
    ChallengeKeep records and names in their own forms
  13. 13
    RecapChoose the effect and the rule

Python Lists and Tuples practice questions

60 Practice Questions in 6 sets

Set 1: Process values, positions and tables10 Practice Questions

Question 1 of 10

What list does this code print?

values = [8, 3]
for value in values:
    value = 0
print(values)
  1. [0, 0]
  2. [8, 3]
  3. [0, 3]
  4. [8, 0]
Show answerHide answer
Answer: B
The loop name value is rebound to 0 on each pass, but no list position is assigned a new value. The original list therefore stays [8, 3]. To produce [0, 0], the loop would need to assign to each list index, such as values[i] = 0.

Question 2 of 10

What value does this code print?

count = 0
for size in [10, 7, 10, 13, 6]:
    if size >= 10:
        count += 1
print(count)
  1. 1
  2. 33
  3. 2
  4. 3
Show answerHide answer
Answer: D
Both occurrences of 10 and the value 13 meet the condition, so the counter increases three times. The result is 3. A count of 1 would use > 10, excluding the boundary values; a total of 33 would add the matching sizes instead of counting them.

Question 3 of 10

For table = [[6, 8, 10], [11, 13, 15]], what does table[1][0] + table[0][2] produce?
  1. 21
  2. 19
  3. 25
  4. 23
Show answerHide answer
Answer: A
The first lookup selects row 1 and then its first item, 11. The second selects row 0 and then its third item, 10, so the total is 21. Using 13 for the first term would take column 1 instead of column 0, mixing the two index roles.

Question 4 of 10

How many pairs does list(zip(["Lee", "Mo", "Nia"], [41, 56])) contain?
  1. 3
  2. 5
  3. 2
  4. 1
Show answerHide answer
Answer: C
zip forms pairs at matching positions and stops when either input ends. There are two scores, so only two name–score pairs can be formed. It does not create a third pair with a missing score, and it does not combine every name with every score.

Question 5 of 10

What is printed?

values = [7, -4, -8, 2]
position = -1
for i, value in enumerate(values):
    if value < 0:
        position = i
        break
print(position, values[position])
  1. 2 -8
  2. -1 2
  3. -4 1
  4. 1 -4
Show answerHide answer
Answer: D
Index 0 fails the test; index 1 contains -4 and succeeds. The code stores 1 and breaks, so the final lookup retrieves values[1], which is -4. Reporting 2 -8 would continue searching and keep the last negative, but break prevents that later update.

Question 6 of 10

How many times does total += value run?

total = 0
for row in [[2, 4], [6], [8, 10, 12]]:
    for value in row:
        total += value
  1. 3
  2. 6
  3. 9
  4. 2
Show answerHide answer
Answer: B
The inner loop runs twice for the first row, once for the second and three times for the third, giving six updates. Counting only three would count rows instead of cells. Nine would assume three cells in every row, but the rows have different lengths.

Question 7 of 10

What list remains after this code?

values = [0, 0, 1, 0]
for value in values:
    if value == 0:
        values.remove(value)
  1. [1]
  2. [0, 0, 1]
  3. [1, 0]
  4. [0, 1]
Show answerHide answer
Answer: C
Removing the first 0 shifts the second 0 into index 0, which the loop has already visited. The loop then visits 1 and the last 0; remove(0) deletes the first remaining zero, leaving [1, 0]. Removing every zero safely requires a copy or a new retained-items list.

Question 8 of 10

A loop must find the largest value in the nonempty list [-14, -6, -19]. What should initialize its running maximum?
  1. The first item, -14.
  2. The number zero, 0.
  3. The length of the list, 3.
  4. The first index, 0.
Show answerHide answer
Answer: A
Starting with the first item gives the running maximum a value that actually occurs in the data. It can then be replaced by -6 when that larger value is visited. Starting at 0 would keep 0 throughout, wrongly reporting a value greater than every reading but absent from the list.

Question 9 of 10

What does this code print?

kept = []
for text in ["4", "15", "8", "21"]:
    number = int(text)
    if number % 2 == 0:
        kept.append(number + 1)
print(kept)
  1. [4, 8]
  2. [5, 9]
  3. [5, 16, 9, 22]
  4. [16, 22]
Show answerHide answer
Answer: B
The strings are first converted to integers. Only 4 and 8 pass the even-number test, and adding 1 to each creates [5, 9]. [4, 8] would filter correctly but omit the transformation; transforming every input would ignore the condition.

Question 10 of 10

What table results?

table = []
for r in range(2):
    table.append([0] * 2)
table[1][0] = 6
  1. [[6, 0], [6, 0]]
  2. [[0, 6], [0, 0]]
  3. [[0, 0], [6, 0]]
  4. [[0, 0], [0, 6]]
Show answerHide answer
Answer: C
Each loop pass constructs a separate row, so assigning row 1, column 0 changes only the second row’s first cell. The result is [[0, 0], [6, 0]]. Both first cells would change if the outer list repeated one shared row reference, but this construction creates a new row each time.
Set 2: Read, slice and change sequences10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

For levels = [14, 29, 37, 52], what is levels[-2]?
  1. 29
  2. 52
  3. 37
  4. 14
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

For codes = [2, 5, 8, 11, 14, 17], what is codes[1:5:2]?
  1. [5, 11]
  2. [5, 8, 11, 14]
  3. [5, 11, 17]
  4. [2, 8, 14]
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

What list results from this code?

items = ["pen"]
items.append(["clip", "pad"])
  1. ['pen', 'clip', 'pad']
  2. [['pen'], ['clip', 'pad']]
  3. ['pen', 'clip pad']
  4. ['pen', ['clip', 'pad']]
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

What does this code print?

parts = "6|12|18".split("|")
print(len(parts), parts[1])
  1. 8 12
  2. 3 12
  3. 3 6
  4. 8 |
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

What is len(values) after this code?

values = [4, 7, 10, 13]
values[1:3] = [20, 21, 22]
  1. 4
  2. 5
  3. 6
  4. 3
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

How do you write a tuple containing only the integer 12?
  1. (12)
  2. [12]
  3. tuple(12)
  4. (12,)
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

What does this code print?

queue = [18, 0, 24]
removed = queue.pop(0)
print(removed, queue)
  1. 18 [0, 24]
  2. 0 [18, 24]
  3. None [0, 24]
  4. 24 [18, 0]
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

What does this code print?

a = [3, 6, 9, 12, 15]
b = a[-4:-1]
print(b[::-1][1])
  1. 6
  2. 12
  3. 9
  4. 15
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

For items = [9, 16, 25], what happens when Python evaluates items[len(items)]?
  1. It raises IndexError.
  2. It returns the last item, 25.
  3. It returns the first item, 9.
  4. It raises TypeError.
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

What does this comparison produce: [4, 99] < [5, 1]?
  1. False, because the second pair is 99 and 1.
  2. False, because the first list has the larger total.
  3. True, because both lists have the same length.
  4. True, because the first unequal pair is 4 and 5.
Show answerHide answer

Save this lesson to see this answer.

Set 3: Unpack records and trace shared objects10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

After label, amount = ("rice", 4), what value does amount hold?
  1. 'rice'
  2. (4,)
  3. ('rice', 4)
  4. 4
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

What is middle after first, *middle, last = (2, 5, 8, 11, 14)?
  1. (5, 8, 11)
  2. [5, 8, 11]
  3. [2, 5, 8, 11]
  4. [5, 8, 11, 14]
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

What does this code print?

a = [5, 8]
b = [5, 8]
print(a == b, a is b)
  1. True True
  2. False True
  3. True False
  4. False False
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

What does this code print?

record = ([2], "ready")
other = record
record[0].append(7)
print(other)
  1. ([2, 7], 'ready')
  2. ([2], 'ready')
  3. ([7], 'ready')
  4. ([2], 'ready', 7)
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

What does this code print?

a = [4]
b = a
a += [9]
a = a + [12]
print(a, b)
  1. [4, 9, 12] [4]
  2. [4, 9, 12] [4, 9, 12]
  3. [4, 9, 12] [4, 9]
  4. [4, 9] [4, 9, 12]
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

What does this code print?

def bounds(values):
    return min(values), max(values)

low, high = bounds([18, 5, 12])
low, high = high, low
print(low, high)
  1. 18 5
  2. 5 18
  3. 18 18
  4. 5 5
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

What does this code print?

a = [2, 6]
b = a.copy()
b[0] = 10
print(a, b)
  1. [10, 6] [10, 6]
  2. [2, 6] [2, 6]
  3. [10, 6] [2, 6]
  4. [2, 6] [10, 6]
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

A program needs a dictionary key representing row 3 and column 7. What value can it use as the coordinate key?
  1. [3, 7]
  2. (3, 7)
  3. ([3], 7)
  4. (3, [7])
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

What does this code print?

a = [[4], [8]]
b = a.copy()
b[0].append(6)
b[1] = [9]
print(a)
  1. [[4], [8]]
  2. [[4, 6], [9]]
  3. [[4], [9]]
  4. [[4, 6], [8]]
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

What does this code print?

row = [1, 2]
table = [row, row]
row = [8, 9]
table[0][1] = 7
print(table, row)
  1. [[1, 7], [1, 7]] [8, 9]
  2. [[8, 7], [8, 7]] [8, 7]
  3. [[1, 7], [1, 2]] [8, 9]
  4. [[1, 2], [1, 2]] [8, 7]
Show answerHide answer

Save this lesson to see this answer.

Set 4: Control changes across function calls10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

What does this code print?

def change(values):
    values.append(8)
    values = [0]
    return values

original = [3]
result = change(original)
print(original, result)
  1. [0] [0]
  2. [3, 8] [0]
  3. [3] [0]
  4. [3, 8] [3, 8]
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

What table results?

table = [[0] * 2] * 3
table[2][1] = 4
table[0] = [9, 9]
  1. [[9, 9], [0, 0], [0, 4]]
  2. [[9, 9], [9, 9], [9, 9]]
  3. [[0, 4], [0, 4], [0, 4]]
  4. [[9, 9], [0, 4], [0, 4]]
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

For codes = ["q", "r", "q", "s", "q"], what is codes.index("q", 1)?
  1. 0
  2. 1
  3. 2
  4. 4
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

For tags = ["new", "old", "new"], what does tags.count("done") return?
  1. 0
  2. -1
  3. None
  4. ValueError
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

What does this code print?

def reset(values):
    values = []

values = [11, 22]
reset(values)
print(values)
  1. []
  2. None
  3. [11, 22]
  4. [0, 0]
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

What does this code print?

import copy
a = [[3], [7]]
b = copy.deepcopy(a)
b[0].append(5)
print(a, b[0] is a[0])
  1. [[3, 5], [7]] True
  2. [[3], [7]] False
  3. [[3], [7]] True
  4. [[3, 5], [7]] False
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

What does the final line print?

def collect(item, items=[]):
    items.append(item)
    return items

first = collect("x")
second = collect("y")
print(first is second, first)
  1. False ['x']
  2. True ['x']
  3. False ['x', 'y']
  4. True ['x', 'y']
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

What does this code print?

def trim(values):
    del values[0]

items = [6, 9, 12]
result = trim(items)
print(items, result)
  1. [9, 12] None
  2. [6, 9, 12] [9, 12]
  3. [9, 12] [9, 12]
  4. None [9, 12]
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

What is printed?

def add(item, values=None):
    if values is None:
        values = []
    values.append(item)
    return values

a = add(4)
b = add(7)
c = add(9, a)
print(a, b, c is a)
  1. [4, 7, 9] [4, 7, 9] True
  2. [4] [7] False
  3. [4, 9] [7] True
  4. [4, 9] [7, 9] False
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

What does this code print?

def edit(rows):
    rows[0].append(5)
    rows.append([9])

original = [[1], [2]]
edit(original[:])
print(original)
  1. [[1], [2]]
  2. [[1, 5], [2]]
  3. [[1, 5], [2], [9]]
  4. [[1], [2], [9]]
Show answerHide answer

Save this lesson to see this answer.

Set 5: Choose sorting rules and resolve ties10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

What value does result hold after nums = [8, 2, 5] and result = nums.sort()?
  1. [2, 5, 8]
  2. [8, 5, 2]
  3. None
  4. [8, 2, 5]
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

What does sorted(["20", "3", "11"]) return?
  1. ['3', '11', '20']
  2. ['20', '3', '11']
  3. ['3', '20', '11']
  4. ['11', '20', '3']
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

What does sorted(["pear", "a", "plum", "to"], key=len) return?
  1. ['a', 'to', 'plum', 'pear']
  2. ['a', 'to', 'pear', 'plum']
  3. ['a', 'pear', 'plum', 'to']
  4. ['pear', 'plum', 'to', 'a']
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

For values = [6, 1, 4], what pair of results comes from values[::-1] and sorted(values, reverse=True), in that order?
  1. [4, 1, 6] and [6, 4, 1]
  2. [6, 4, 1] and [4, 1, 6]
  3. [4, 1, 6] and [4, 1, 6]
  4. [6, 4, 1] and [6, 4, 1]
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

Records are (name, score) pairs. What key function body ranks higher scores first and names A to Z when scores tie?
  1. return (record[1], record[0])
  2. return (record[0], -record[1])
  3. return (-record[1], len(record[0]))
  4. return (-record[1], record[0])
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

What order does this code produce?

records = [("Zoe", 8), ("Ali", 8), ("Mia", 6)]
def by_score(record):
    return record[1]
print(sorted(records, key=by_score, reverse=True))
  1. [('Ali', 8), ('Zoe', 8), ('Mia', 6)]
  2. [('Mia', 6), ('Zoe', 8), ('Ali', 8)]
  3. [('Zoe', 8), ('Ali', 8), ('Mia', 6)]
  4. [('Zoe', 8), ('Mia', 6), ('Ali', 8)]
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

What does this code print?

words = ["oak", "elm", "pine", "ash"]
print(max(words, key=len), min(words, key=len))
  1. pine oak
  2. pine ash
  3. 4 3
  4. pine elm
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

What does this code print?

words = ["beta", "Alpha", "alpha", "Beta"]
print(sorted(words, key=str.lower))
  1. ['beta', 'Beta', 'Alpha', 'alpha']
  2. ['Alpha', 'alpha', 'beta', 'Beta']
  3. ['Alpha', 'beta', 'alpha', 'Beta']
  4. ['Alpha', 'Beta', 'beta', 'alpha']
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

What does this code print?

a = [9, 4, 7]
b = a
c = sorted(a)
a.reverse()
print(b, c)
  1. [7, 4, 9] [4, 7, 9]
  2. [4, 7, 9] [4, 7, 9]
  3. [9, 4, 7] [4, 7, 9]
  4. [7, 4, 9] [9, 7, 4]
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

A program first sorts (name, score) records by name A to Z. It then stably sorts them by score, high to low. How are equal-score records ordered in the final list?
  1. By name Z to A within each equal-score group.
  2. By name A to Z before any score comparisons.
  3. By their order before either sort was performed.
  4. By name A to Z within each equal-score group.
Show answerHide answer

Save this lesson to see this answer.

Set 6: Debug and combine sequence operations10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

For values = [12, 24], what is values[5:20]?
  1. IndexError
  2. []
  3. [24]
  4. [12, 24]
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

A numeric list may be empty. How can a function return its mean when values exist and None otherwise?
  1. Test if not values: return None, then return sum(values) / len(values).
  2. Test if not values: return 0, then return sum(values) / len(values).
  3. Return sum(values) / len(values) before testing whether it is empty.
  4. Test if values: return None, then return sum(values) / len(values).
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

What does this code print?

items = [1, 2]
result = items.extend([3, 4])
print(len(items), result)
  1. 3 None
  2. 4 [1, 2, 3, 4]
  3. 2 [3, 4]
  4. 4 None
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

What does this code print?

records = [("A", 4), ("B", 9)]
amounts = []
for _, amount in records:
    amounts.append(amount)
first, *rest = amounts[::-1]
print(first, rest)
  1. 4 [9]
  2. 9 (4,)
  3. 9 [4]
  4. [9] 4
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

What does this code print?

values = [5, -2, 8, -4]
for i, value in enumerate(values):
    if value < 0:
        values[i] = -value
print(values[1::2])
  1. [2, 4]
  2. [-2, -4]
  3. [5, 8]
  4. [5, 2, 8, 4]
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

What does this code print?

a = [[9, 2], [8, 1]]
b = a[:]
b.reverse()
b[0][0] = 6
print(a)
  1. [[6, 1], [9, 2]]
  2. [[9, 2], [8, 1]]
  3. [[9, 2], [6, 1]]
  4. [[6, 2], [8, 1]]
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

What does this code print?

records = [("Rae", 7), ("Dev", 9), ("Cam", 7)]
def rank(record):
    return (-record[1], record[0])
ordered = sorted(records, key=rank)
name, score = ordered[1]
print(name, score)
  1. Rae 7
  2. Cam 7
  3. Dev 9
  4. Cam -7
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

What does this code print?

def select(values):
    kept = []
    for value in values:
        if value >= 5:
            kept.append(value * 2)
    return kept

a = [3, 5, 8]
b = select(a)
b.pop(0)
print(a, b)
  1. [3, 5, 8] [10, 16]
  2. [5, 8] [16]
  3. [3, 5, 8] [10]
  4. [3, 5, 8] [16]
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

A nonempty odd-length list is [31, 12, 27, 18, 24, 15, 21]. After sorting a copy, what is the middle value?
  1. 18
  2. 21
  3. 24
  4. 27
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

What does this code print?

point = (6, 8)
old = point
point = (10,) + point[1:]
print(old, point)
  1. (6, 8) (10, 8)
  2. (10, 8) (10, 8)
  3. (6, 8) (6, 10)
  4. (6, 8) (10,)
Show answerHide answer

Save this lesson to see this answer.

Stuck on your own question? Homework Help

Key Terms

73 Key Terms, each with its definition

A

Accumulator
An accumulator is a variable that retains a running result across loop passes, such as a total updated by adding each item.
Set total = 0 before processing readings, then use total += reading to retain earlier additions.
Alias
An alias is another name or reference for the same object, allowing a mutation made through one path to appear through another.
If current = queue, appending through current also changes the list reached through queue.
append()
The append() list method adds its argument as one item at the end of the existing list and returns None.
Appending [3, 4] to [1, 2] produces [1, 2, [3, 4]], because the argument stays one item.

C

Case-insensitive key
A case-insensitive key compares normalized text values while keeping each original string’s spelling in the returned collection.
key=str.lower lets "Oak" and "oak" compare equally without changing their capital letters.
Cell
A cell is one value in a table, reached by selecting its row and then its position within that row.
grid[0][2] = 9 replaces the first row’s third cell, assuming that position already exists.
Concatenation
Concatenation joins sequences end to end; list concatenation with + creates a new outer list from two lists.
morning + afternoon can combine two lists of readings while leaving each original list intact.
count()
The count() list method returns the number of items equal to its argument and returns 0 when the value is absent.
[2, 2.0, 5].count(2) is 2 because both the integer 2 and the float 2.0 compare equal to 2.
Counter
A counter is a variable that records how often a condition is met, commonly starting at 0 and increasing by 1 per match.
A score counter adds 1 for each passing score, regardless of whether that score is 60 or 100.

D

Deep copy
A deep copy recursively duplicates a nested structure so changes to copied inner lists do not reach the original inner lists.
copy.deepcopy(rows) can preserve original table cells while a separate nested structure is edited.
Descending order
Descending order puts larger comparison values before smaller ones and is requested with the named sorting option reverse=True.
Descending sorting of [5, 1, 8] gives [8, 5, 1]; reversing its positions alone gives [8, 1, 5].

E

enumerate()
The enumerate() built-in supplies pairs containing a running number and an item, beginning with number 0 by default.
for i, value in enumerate(values): gives code both an index and its corresponding current item.
extend()
The extend() list method adds each item from an iterable to the end of the existing list and returns None.
Extending [1, 2] with [3, 4] produces four outer items; extending with "ab" adds two characters.

F

Filtering
Filtering builds a collection of items that satisfy a condition while leaving out items that fail that condition.
A loop can append only scores of at least 60 to a new list, preserving the original score order.
First-match search
A first-match search visits items until one satisfies a test, saves its result and stops before later matches can replace it.
A loop can store the first negative reading’s index and use break to finish the search immediately.

H

Hashable value
A hashable value supports the stable lookup rules needed for dictionary keys; tuples require hashable contents, and lists are unhashable.
(5, 9) can be a coordinate key, but ([5], 9) cannot because its inner list is unhashable.

I

Identity
Identity is the property of being the same object, tested by is; equal contents can belong to different list objects.
Two separate [1, 3] literals compare equal, but an identity check between those lists is false.
Immutability
Immutability means an object’s own state cannot be changed in place; a tuple fixes its item references, not mutable objects inside it.
A tuple containing a list cannot replace that list position, but the stored list can still receive an append.
In-place operation
An in-place operation changes an existing object so other references to that object observe the same changed state.
values.clear() empties the existing list, so every alias sees that list become empty.
Index
An index is an integer position used to select an item; Python counts from 0 at the start or from -1 at the end.
For colors = ["blue", "gold"], index 1 selects 'gold', which is also the item at index -1.
index()
The index() list method finds the first equal item in its search range and returns that item’s index in the whole list.
labels.index("go", 2) begins searching at position 2 but still counts its answer from position 0.
insert()
The insert() list method adds an item before a specified position, shifting later items and increasing the list’s length.
queue.insert(0, "urgent") places a new item at the front without overwriting the previous first item.
Item
An item is one value held at a position in a collection; a nested list counts as one item of its outer list.
In ["desk", ["pen", "pad"]], the outer list has two items, even though the inner list contains two strings.
Item assignment
Item assignment replaces the object at an existing mutable sequence position and leaves the outer sequence’s length unchanged.
prices[1] = 6.5 corrects one recorded price; it cannot create an item at index len(prices).
Iterable
An iterable is an object that can supply items one at a time to a loop or to a function such as list().
A range supplies numbers, so list(range(3)) collects them into the new list [0, 1, 2].
Iteration
Iteration is repeated processing of items supplied in turn, such as a for loop visiting a list from its first item to its last.
A loop over names assigns each current name to the loop variable before running its body.

J

join()
The join() string method combines supplied strings into one string, placing the string it is called on between items.
" / ".join(["red", "blue"]) makes 'red / blue'; numeric items must first be converted to strings.

K

Key function
A key function computes one comparison value from each input item while leaving the original items intact in the sorted output.
Using key=len orders words by length without replacing those words with their length numbers.

L

Lexicographic order
Lexicographic order compares sequences from left to right, with the first unequal pair deciding or a shorter matching prefix first.
[3, 20] < [4, 1] is true because the first items decide the order before the second items are compared.
List
A list is an ordered, mutable collection whose items can be read by position and may contain repeated values or different types.
A program can store several quiz results in scores = [73, 91, 73] and process them together.
List parameter
A list parameter is a local function name initially referring to the caller’s list object, allowing the function to mutate that object.
A function that calls values.clear() empties the caller’s list; assigning values = [] does not.
Loop variable
A loop variable is a name bound to the current item on each pass; rebinding it does not assign into the original list.
In for value in values: value = 0, the loop name changes but the stored list positions do not.

M

Mean
The mean of a nonempty numeric collection is its total divided by its item count; an empty collection has no mean here.
For readings [6, 10, 14], sum(readings) / len(readings) computes the mean as 10.0.
Median
The median is the middle value in sorted data; for a nonempty odd-length list it is the item at index len(ordered) // 2.
Sorting [5, 12, 2] gives [2, 5, 12], placing the median 5 at the middle index 1.
Membership test
A membership test checks whether an equal value occurs in a collection and returns a Boolean result through in or not in.
"ready" in statuses can decide whether a list contains that exact, case-sensitive status string.
Method
A method is a function associated with an object and called through dot notation to perform an operation on that object.
queue.append("next") calls the list’s method and supplies the item to add as its argument.
Mutable default argument
A mutable default argument is a changeable object created when a function is defined and reused by calls that omit that argument.
A default basket=[] keeps appended items between default calls because each call reaches the same list.
Mutation
Mutation changes an existing object’s contents or state, so every reference to that object can observe the same change.
items[0] = 7 mutates the list; any alias to that list sees its first position become 7.

N

Nested list
A nested list is a list containing other lists; each inner list is an item that can be reached and processed separately.
In [[2, 5], [7]], the outer list contains two rows whose lengths are two and one.
Nested loop
A nested loop is a loop inside another loop; the inner loop completes its work for each pass of the outer loop.
A row loop containing a cell loop can process tables with different numbers of items in each row.
None default
A None default can mark an omitted list argument so a function creates a fresh list inside its body for each default call.
With values=None, the branch if values is None: values = [] avoids an accidentally shared default list.

O

Omitted bound
An omitted bound lets a slice use the appropriate end of a sequence, depending on whether its step moves forward or backward.
In values[::-1], omitted bounds let the backward slice include the whole list in reversed order.
One-item tuple
A one-item tuple is a tuple with a single position, written with a trailing comma to distinguish it from a grouped expression.
(11,) is a tuple, whereas (11) evaluates to the integer 11 without making a collection.
Outer list
An outer list is the container holding inner objects; changing one of its positions differs from mutating the object in that position.
b[0] = [9] replaces a row reference, while b[0].append(9) changes the existing row object.

P

Packing
Packing collects multiple expression values into one tuple, commonly using commas without requiring surrounding parentheses.
result = lowest, highest stores both values in a tuple that can be returned from a function.
pop()
The pop() list method removes and returns an item by index, using the last position when no index is supplied.
current = queue.pop(0) saves the first queued item and removes that position from the existing list.

R

Rebinding
Rebinding changes the object a name refers to without redirecting other names that referred to the previous object.
After b = a, assigning b = [] gives b a new list while a continues to refer to the original.
Record
A record is a group of related fields describing one entity, often stored as a tuple whose positions have distinct meanings.
("Kai", 86) can represent a name and score; a list of such records can grow as results arrive.
Reference
A reference connects a name or container position to an object; copying that reference does not copy the object itself.
b = a gives both variable names a path to the same list, so edits can be shared.
remove()
The remove() list method deletes the first item equal to its argument and raises ValueError when no match exists.
labels.remove("old") deletes one matching value; it does not interpret "old" as a position.
Repetition
Repetition uses * with an integer to repeat a sequence’s item references in order, producing an empty sequence for nonpositive counts.
[0] * 5 creates five counter positions, while repeating a row list can create shared inner rows.
Return value
A return value is the object a function call produces for its caller, separate from any changes made to arguments during the call.
A function may append to a list and still return None when its body has no explicit return statement.
Reversal
Reversal flips a sequence’s existing order without choosing positions by value, so it need not produce ascending or descending order.
values.reverse() mutates a list, while values[::-1] creates a reversed shallow copy.
reversed()
The reversed() built-in supplies sequence items from last to first without rearranging the sequence’s stored positions.
for task in reversed(tasks): processes the last task first while keeping the original list order.
Row
A row in a list-based table is one inner list, selected by the first index before a second index selects a cell within it.
grid[1] retrieves the entire second row, so len(grid[1]) counts that row’s cells.
Running maximum
A running maximum is the largest item seen so far, initialized from an actual item and replaced whenever a larger item arrives.
Starting from the first reading lets the pattern correctly find the largest value when all readings are negative.

S

Shallow copy
A shallow copy creates a new outer container while retaining references to the original items, including any mutable inner lists.
After b = a.copy(), appending to b changes its outer list, but editing a shared row can affect a too.
Shared row
A shared row is one inner list referenced by several table positions, so a cell edit can appear in more than one displayed row.
table = [row, row] stores one row twice, even though printing the table displays two row positions.
Simultaneous swap
A simultaneous swap evaluates both old values before assigning them to the opposite names in one unpacking statement.
left, right = right, left preserves both values without requiring a separately named temporary value.
Slice
A slice selects a sequence of items using boundaries and an optional step, returning a new sequence of the original type.
tasks[1:4] makes a list from positions 1, 2 and 3 without including the item at position 4.
Slice assignment
Slice assignment replaces a selected range in a mutable sequence; a contiguous range can receive a different number of items.
values[1:2] = [8, 9] replaces one position with two values, increasing the list’s length by one.
Slice step
A slice step is a nonzero integer that controls the spacing and direction between selected sequence positions.
values[1::2] selects every second position starting at 1; a negative step moves backward.
sort()
The sort() list method rearranges the existing list by comparison order and returns None, with optional key and reverse arguments.
scores.sort() changes the recorded order directly, and aliases to scores see the sorted positions.
sorted()
The sorted() built-in accepts an iterable and returns a new list of its items in comparison order, leaving the input order unchanged.
ordered = sorted(scores) keeps the original arrival order available through the scores variable.
split()
The split() string method divides text into a list of string pieces using a specified separator or whitespace rules.
"yes|no|maybe".split("|") creates three separate text items from the separator-delimited input.
Stable sorting
Stable sorting preserves the relative input order of items whose comparison keys are equal, including when sorting in descending order.
Words with equal lengths remain in their original relative order when the only key function is len.
Starred name
A starred name in unpacking collects all values not assigned to the unstarred targets and always receives a list.
In first, *rest = (4, 8, 12), rest is [8, 12], even though the input is a tuple.
Stop boundary
A stop boundary is the excluded endpoint of a slice; the selected positions end before that boundary in the step’s direction.
In values[2:5], index 5 marks where selection stops and does not contribute an item.

T

Tie-breaker
A tie-breaker is a secondary comparison rule used when an earlier rule gives equal keys, such as comparing names after equal scores.
Two records with score 80 can be ordered by name when the key includes that name after the score.
Transformation
A transformation computes an output value from an input item, often building a new list with one result per original item.
Appending int(text) for each numeric string builds a list that can be totaled with sum().
Tuple
A tuple is an ordered sequence whose item positions cannot be replaced, added or removed after the tuple is created.
location = (5, 9) stores a fixed coordinate pair, which still supports indexing and slicing.
Tuple key
A tuple key combines comparison fields in priority order, with later fields deciding only when all preceding fields tie.
Returning (-score, name) ranks scores high to low and uses names A to Z to break score ties.

U

Unpacking
Unpacking assigns items from an iterable to multiple targets in order, requiring matching counts unless a star collects leftovers.
name, score = ("Kai", 86) gives each record field a separate, meaningful variable name.

Z

zip()
The zip() built-in pairs corresponding items from input iterables and, by default, stops when the shortest input ends.
Pairing three names with two scores creates two pairs; the unmatched name needs a separate decision.

About this lesson

By StudeliReport a mistake

Make your own Study Materials

Turn your notes, slides and documents into Study Guides, Practice Questions, Flashcards and 6 more tools.

Get Started