I want to pass a new instance of 2D array to a function. I have tried the common answers like using the list(old) or doing a old[:]. Still I am getting the same reference.
The only reason I can think of is using nested methods which I don't understand well due to my C background. If anyone can explain why the code is behaving in this way it would really help me understand the magic of python.
Code for reproduction (Edited to make it minimal and more descriptive)-
from pprint import pprint as pp
class Solution:
def solveNQueens(self, a):
b1 = [['.' for i in range(a)] for j in range(a)] #base list with queens positions and empty positions
b2 = list(b1) #to make a seperate list with na positions marked as x
def fillRows(i, j, b, p):
b[i][j] = 'Q' #add queens position
for x in range(i + 1, a):
p[x][j] = 'x' #cross straight entries
return b, p
def queenFill(i, b, p):
for j, e in enumerate(p[i]):
if e == '.':
pp(p)
bx = []
bx.extend(b) # trying to create new array duplicate that original array is unaffected by fillRows
# but as seen from print p is getting changed still, it should be same for every print call
px = []
px.extend(p)
bt, pt = fillRows(i, j, list(bx), list(px)) #trying to create new array duplicate using another method
queenFill(0, b1[:], b2[:]) #trying to create new array duplicate using another method
s = Solution()
s.solveNQueens(4)
The output I am getting is -
[['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.']]
[['Q', '.', '.', '.'],
['x', '.', '.', '.'],
['x', '.', '.', '.'],
['x', '.', '.', '.']]
[['Q', 'Q', '.', '.'],
['x', 'x', '.', '.'],
['x', 'x', '.', '.'],
['x', 'x', '.', '.']]
[['Q', 'Q', 'Q', '.'],
['x', 'x', 'x', '.'],
['x', 'x', 'x', '.'],
['x', 'x', 'x', '.']]
While it should be like this as I am not changing the varible I am printing anywhere, I am creating duplicate of that -
[['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.']],
[['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.']]
[['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.']]
[['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.'],
['.', '.', '.', '.']]
b1
is a list
that contains inner list
s. Copying it, either using list(b1)
or b1[:]
copies the outer list
, but not the inner list
s.
If you want to copy the inner lists as well, try using copy.deepcopy
.