Thursday, March 28, 2019

Function in Python Setting Global Variables (without intent)



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?


Answer




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.



No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...