Data Structures and Object-Oriented Programming

Chapter 4: 2D Lists and Tuples

1. What a 2-D list really is

A 2-D list is just "a list of lists." Think of the outer list as the rows of a table and each inner list as that row's columns:

grades = [
    [75, 82, 91],   # row 0
    [88, 90, 79]    # row 1
]
  • Indexing: grades[row][col] *grades[1][2] → 79 (row 1, column 2).
  • Typical uses: grids for games, seating charts, matrices in math, simple images.

2. Traversing every cell with nested loops

The outer loop walks through rows, the inner loop walks through columns in that row:

for r in range(len(grades)):          # every row
    for c in range(len(grades[r])):   # every column in that row
        print(grades[r][c])

If the grid has m rows and n columns, the nested loops run m × n steps ⇒ O(m n) time.


3. Example walk-through: finding the max

def max2d(mat):
    best = mat[0][0]                 # start at first cell
    for r in range(len(mat)):
        for c in range(len(mat[r])):
            if mat[r][c] > best:     # found something larger
                best = mat[r][c]
    return best

Try it on [[1,2,3],[4,5,6]]; the variable best climbs 1 → 2 → 3 → 4 → 5 → 6, finally returning 6.


4. Common gotcha: "shared references"

Assigning one list variable to another does not make a copy:

a = [[1, 2], [3, 4]]
b = a        # b points to the *same* object
b[0][0] = 99
print(a)     # [[99, 2], [3, 4]]

Use copy.deepcopy(a) or a list comprehension if you really need an independent copy.

Slide questions 10 & 16 in your PDF show exactly this trap and how the inner data can change both names .


5. Quick practice (derived from the slides)

Example 1: Type error with list + tuple

nums=[1,2,3,4,5]
for i in range(len(nums)):
    nums[i]*=2
nums = nums + (6,7)  # TypeError: can only concatenate list to list

What happens? TypeError
Why? + can join list + list, but here we tried list + tuple

Example 2: Type error with += and tuple

nums=[1,2,3,4,5]
nums += (2,3)  # TypeError: 'tuple' object cannot be interpreted as an integer

What happens? Also TypeError
Why? += on a list expects another list

Example 3: Mutable list inside a tuple

t=('apple',17.3,[99,98])
num=t[2]
num[1]=0
print(t)  # ('apple', 17.3, [99, 0])

What happens? ('apple', 17.3, [99, 0])
Why? Tuple itself is frozen, but the list inside is still mutable

(You will see these exact scenarios in the ConcepTests.)


6. Tuples ― the read-only cousin of lists

FeatureListTuple
Mutable?✔ Yes✖ No – size & order fixed
Literal[1, 2](1, 2) or 1, 2
Methods.append(), .pop(), …Only .count(), .index()
Speed / safetySlightly slower, unrestrictedSlightly faster, safe to hash/use as dict key

Adding vs. modifying

  • You can add tuples together to build a new one: months = ('Jan',) + ('Feb','Mar')
  • You cannot change an element: months[0] = 'Dec' # TypeError

6.1 Mutable items inside a tuple

A tuple may contain a list; the tuple shell stays fixed, but the list's contents can change:

score = (1, [2, 3], 4)
score[1].append(5)      # legal
score                    # (1, [2, 3, 5], 4)

7. Recognising time-cost patterns

PatternTime complexityWhy
Single loop through list length nO(n)touches each element once
Nested loop over m rows × n colsO(m n)visits every cell
Square matrix (n×n)O(n²)special case of above

8. Checklist for your exam

  1. Index order: [row][col], never mix them up.
  2. Copying vs. aliasing: slice (a[:]) gives a shallow copy; nested lists still alias.
  3. Immutable errors: watch out for TypeError: 'tuple' object does not support item assignment.
  4. Time complexity talk: be ready to justify O(n) vs. O(n²).
  5. Mutable-in-tuple trick: legal but exam questions may test your understanding.

9. Want more practice?

  • Re-trace the ConcepTest problems in the slides and predict the output before running them.
  • Write a function that adds two 2-D matrices of the same size and analyse its running time.
Back to Data Structures and Object-Oriented Programming