List & Tuple
Building Lists of Lists
Method 1
Create a list of three lists of three items each. Inspect the structure.
Place a mark in row 1, column 2, and check the result.
board = [['_'] * 3 for i in range(3)]
print(board)
>>> [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
board[1][2] = 'X'
print(board)
>>> [['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]
board = []
for i in range(3):
# Each iteration builds a new row and
# appends it to board
row = ['_'] * 3
# Only row 2 is changed, as expected
board.append(row)
Method 2
The outer list is made of three references to the same inner list. While it is unchanged, all seems right.
Placing a mark in row 1, column 2, reveals that all rows are aliases referring to the same object.
weird_board = [['_'] * 3] * 3
print(weird_board)
# Outer list is made of three reference to the same inner list
>>> [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
# All rows are aliases referring to the same object
weird_board[1][2] = 'O'
print(board)
>>> [['_', '_', 'O'], ['_', '_', 'O'], ['_', '_', 'O']]
row = ['_'] * 3
board = []
for i in range(3):
# The same row is appended three times to board
board.append(row)
Beware of expressions like a * n
when a
is a sequence containing mutable items because the result may surprise you.
For example, trying to initialize a list of lists as my_list = [ [] ]
*
3
will result in a list with three references to the same inner list, which is probably not what you want.
Augmented Assignment with Sequences
+=
and *=
operators produce very different results depending on the mutability of the target sequence
if __iadd__
is not implemented, Python falls back to calling __add__
-> a += b == a = a+b
.
Repeated concatenation of immutable sequences is inefficient, because instead of just appending new items. The interpreter has to copy the whole target sequence to create a new one with the new items concatenated.
There is one strange situation – tuple assignment puzzler,
# What do you expect in the output
t = (1, 2, [30, 40])
t[2] += [50, 60]
# A: t becomes (1, 2, [30, 40, 50, 60])
# B: TypeError is raised with the message 'tuple' object
# does not support item assignment
# C: Neither
# D: Both A and B
Answer:
t = (1, 2, [30, 40])
try:
t[2] += [50, 60]
except Exception as e:
print(e)
print(t)
# Output:
# >>> 'tuple' object does not support item assignment
# >>> (1, 2, [30, 40, 50, 60])
Playground
Last updated
Was this helpful?