Reputation: 21
I was playing around with python for the last few days and I keep getting a weird problem. (For reference, I'm working on project euler's 345.) So... I'm trying to zero a row and a column of a 2D array, but not the point where they intersect. Now, I understand that there might be a more pythonic way of solving this, but I'm mainly concerned with why the code I have here isn't working.
def choose(initial_grid,row,col):
"""Return a grid with a given row and column zeroed except where intersect.
"""
grid = list(initial_grid) #FLAG 1
Special_value = grid[row][col]
grid[row] = [0]*len(grid[row])
for i in xrange(len(grid)):
grid[i][col] = 0
grid[row][col] = Special_value
return grid
qwer = [[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12],
[13,14,15,16]]
print choose(qwer,1,1)
print qwer
Anyways, I'd expect the function output to be
[[1, 0, 3, 4], [0, 6, 0, 0], [9, 0, 11, 12], [13, 0, 15, 16]]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
But... It isn't. For whatever reason, qwer
gets its column 1 cleared. I've tried doing a list copy to dereference the pointer passed by initial_grid,
and I've tried using grid = initial_grid[:]
, but nothing seems to work.
So what's wrong? How do I fix this? And why is this wrong?
Upvotes: 0
Views: 433
Reputation: 78760
list(initial_grid)
makes a shallow copy of your list. The inner lists are not copied.
Demo:
>>> l = [[1, 2], [0, 0]]
>>> c = list(l)
>>> l is c
False
>>> all(x is y for x,y in zip(l, c))
True
>>> c[0][0] = 5
>>> c
[[5, 2], [0, 0]]
>>> l
[[5, 2], [0, 0]]
If you want a deep copy, use copy.deepcopy
. Or for a 2D list, write
>>> d = [sub[:] for sub in l]
>>> d[0][0] = 7
>>> d
[[7, 2], [0, 0]]
>>> l
[[5, 2], [0, 0]]
Also, your lingo is off. We don't have pointers in Python. We have names and values.
Upvotes: 1