I read this about Python classes (link) and it seems to be the issue I am having.
Here is an excerpt from my class and other code:
class s_board:
def __init__(self):
self.__board = [[n for n in range(1, 10)] for m in range(81)]
self.__solved = [False for m in range(81)]
def copy(self):
b = s_board()
b.__board = self.__board[:]
b.__solved = self.__solved[:]
return b
if __name__ == '__main__':
A = s_board()
B = A.copy()
B.do_some_operation_on_lists()
When I call B’s method that does something to the list, A’s lists seem to be affected as well.
So my questions:
- Am I not copying the class or the lists correctly?
- Is there another issue here?
- How do I fix it so that I get a new copy of the class?
self.__board[:]creates a new list containing references to all the same objects that were inself.__board. Sinceself.__boardcontains lists, and lists are mutable, you end up with the twos_boardinstances with partially aliased data, and changing one affects the other.As Raymond Hettinger suggested, you can use the
copy.deepcopyto (mostly) guarantee that you take a true copy of an object and don’t share any data. I say mostly, as I believe there are some strange objects thatdeepcopywill not work on, but for normal things like lists and straightforward classes it will work fine.I have an additional suggestion though. You call
b = s_board(), which goes to all the effort of constructing the lists for the new blank board, and then you throw them away by assigning tob.__boardandb.__solved. It seems to be like it would be better to do something like the following:Now if you call
A = s_board()you get a new blank board, and if you callA.copy()you get a distinct copy ofA, without having had to allocate and then discard a new blank board.