3

I don't know if this is a problem that others get, but I have code in python that goes like this:

def makemove(board,move,val):
    new=board
    new[move[0]][move[1]]=val
    return new

My problem is that if I use this function by simply doing makemove(game,[0,1],-1) where game equals [[0,0,1],[0,1,0],[1,0,0]] the variable game becomes [[0, -1, 1], [0, 1, 0], [1, 0, 0]].

I have tried to look into functions setting global variables, but I have thus for not found a way to prevent makemove() from setting the variables that you put into it. Is there something obvious that I'm missing?

2 Answers2

2

You need to clone board.

import
new = copy.deepcopy(board)

see https://stackoverflow.com/a/2612815/93910 for other ways of doing this.

Your code sets elements of a variable which is a "reference". In other words, your variable new is really an array reference to board, i.e. it points to the same memory location. So when you change new, the original variable board gets changed.

Here's another answer on how to think about this: https://stackoverflow.com/a/9697367/93910

Community
  • 1
  • 1
Sanjay Manohar
  • 6,920
  • 3
  • 35
  • 58
1

This is basically because assignment in Python doesn't mean what you think it does, and lists are mutable sequences.

Lists are Python objects. The name board is merely a label for or reference to that object. So when you say new=board this means "let the name new reference the same object as the name board".

In Python every object has a unique identifier that you can retrieve using id(). Let's create a board, do the assignment and see what happens:

In [1]: board = [[0,0,1],[0,1,0],[1,0,0]]

In [2]: new = board

In [3]: id(new), id(board)
Out[3]: (34495504136, 34495504136)

new and board are referencing the same object.

Since a list is a mutable sequence you can change it without getting an error.

So if you want to play with any mutable sequence inside a function without modifying the original, you should use copy.deepcopy first to make a copy and modify that.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94