Copying a list
When you want a second list that you can change on its own, you have to make a copy. The long way is a new empty list and a loop that appends each item to it:
original = [3, 1, 2]
duplicate = []
for item in original:
duplicate.append(item)
duplicate.append(4)
print(original)
print(duplicate)
[3, 1, 2]
[3, 1, 2, 4]Now there are two lists, and changing one leaves the other alone. Python has three shorter ways to do the same, and each of them gives a new list with the same items:
>>> original = [3, 1, 2]
>>> a = original.copy()
>>> b = original[:]
>>> c = list(original)
>>> a.append(4)
>>> b[0] = 99
>>> c.sort()
>>> original
[3, 1, 2]
>>> a
[3, 1, 2, 4]
>>> b
[99, 1, 2]
>>> c
[1, 2, 3]copy()is a list method that does just that.[:]is a slice with no start and no end, so it takes every item. A slice is always a new list.list(...)builds a new list from the items it's given, as it does withrange.
All three work. copy() is the easiest to read, because it says what it does.
Copying a list of lists
A copy holds the same items as the original. When those items are lists, as in a matrix, the copy holds references to the very same inner lists. The two outer lists are separate, but they share their rows:
board = [[".", "."], [".", "."]]
saved = board.copy()
board[0][0] = "X"
board.append(["new", "row"])
print(saved)
[['X', '.'], ['.', '.']]The new row went into board only, because the outer lists are separate. But the "X" went into a row that both lists share, so it shows up in saved too. To copy a matrix so that nothing is shared, copy each row as well:
board = [[".", "."], [".", "."]]
saved = []
for row in board:
saved.append(row.copy())
board[0][0] = "X"
print(board)
print(saved)
[['X', '.'], ['.', '.']]
[['.', '.'], ['.', '.']]