0

I have a function that looks like this https://i.stack.imgur.com/PQTjc.png I assign the variable test to board[:] (board is an 8x8 list of lists). Later in the function I make a change to test, and send test to another function. The problem is: when test gets changed, the same change happens to board. Any tips to solve this?

code:

def move(piece, loc):
    global board
    test = board[:]
    global count
    global turn
    loc0 = location(piece)
    if count % 2 == 0:
        turn = "w"
    else:
        turn = "b"
    if piece:
        if legal(piece, loc):
            test[loc0[0]][loc0[1]] = ""
            test[loc[0]][loc[1]] = piece
            print(test[5],board[5])
            if check(test) == False:
                board = test[:]
                count += 1
                paint(board)
            print(test[5],board[5])

I tried to use assign test to board[:] to store it in a diffrent place or something, but it still didn't work.

tedch
  • 1
  • 1
  • Welcome to Stack Overflow! Please edit your question so it includes your code as text, not as an image. See ["How do I ask a good question?"](https://stackoverflow.com/help/how-to-ask). – Jasmijn Nov 10 '22 at 16:31

1 Answers1

-1

Usually to avoid this you have to copy

# In Python 3 whether you have a list or np.array or pd.DataFrame
test = board[:].copy()

Then the two variables are decorrelated

nsaura
  • 306
  • 2
  • 11
  • This will do *nothing*, the "empty" (or "complete" if you prefer) slice of a `list` is already a shallow copy (in the past, `list`s didn't even have a `.copy()` method because `thelist[:]` was already how you performed a shallow copy, the method was added mostly for consistency with `set` and `dict` which can't be sliced), and `.copy()` just makes another shallow copy of it and throws away the original shallow copy. – ShadowRanger Nov 10 '22 at 16:33
  • A slice generally makes a copy (at least using standard datatypes, I'm not sure if that goes for numpy and pandas). So `board[:]`, `board.copy()` and `board[:].copy()` all have the same effect (the last one makes an extra copy, just to throw away) – Jasmijn Nov 10 '22 at 16:33
  • I just have the same problem as the author of the question and using the .copy() solves the problem in my case and previous cases – nsaura Nov 10 '22 at 16:35
  • @nsaura: If you're using *`list`s*, I 100% guarantee you are wrong. If you're using `numpy` arrays, it can help (`numpy` slicing violates the normal rules for built-ins by producing views of the original data, not shallow copies). The only built-in type I know of that doesn't shallow copy on being sliced is `memoryview` (and it doesn't have a `copy` method). The OP claims to be using a true `list` of `list`s, and `thelist[:].copy()` is just a slow way to spell either `thelist[:]` or `thelist.copy()` (both of the latter are equivalent). – ShadowRanger Nov 10 '22 at 16:36
  • Indeed my case was for pandas and previous experiences with np.array – nsaura Nov 10 '22 at 16:39
  • @nsaura: Odds are the `[:]` would be pointless even in that case (the `.copy()` would be enough; I'm not *100%* sure the `[:]` is pointless given how complicated the slicing rules are for `numpy`), but yes, that would matter for `numpy`. Of course, for `numpy`, the `[:]` alone isn't even shallow-copying (it makes a new object that happens to point to the same data as the original), so it's very different in multiple ways. – ShadowRanger Nov 10 '22 at 16:41
  • Yes I was also wondering about the [:]. According to other answers, it seems that the shallow copy made by the slice (in the list) can be insufficient (I still don't really understand how it works) in that case you should import deepcopy from copy package (from copy import deepcopy) – nsaura Nov 10 '22 at 16:47
  • 1
    @nsaura: The slice (or `.copy()`) is a shallow copy, copying the outer `list`, but just copying over aliases to all the contained `list`s to the new outer `list`. That's why it's not enough, and why a recursive deep copy is needed. – ShadowRanger Nov 10 '22 at 17:19