![]() |
how can a variable change if I haven't changed it? - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: how can a variable change if I haven't changed it? (/thread-33227.html) |
how can a variable change if I haven't changed it? - niminim - Apr-07-2021 I'm totally new to python. I'm writing a simple code that is supposed to find random bingo statistics. The code works just fine until I'm trying to run it more than once in a for loop. Forget about the code, just check out the oldmatrix variable. I never set a new value to it and yet it changes on the second iteration. How can it be?? # Online Python compiler (interpreter) to run Python online. # Write Python 3 code in this online editor and run it. import random print("Hello world") bingo = 0 checkbingo = 0 basematrix = [[0,0,0,0,0],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0]] matrix = [[0,0,0,0,0],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0]] baselist = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24] list = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24] for iter in range(2): print("ïter =", iter) print("basematrix = ", basematrix) print("matrix = ",matrix) #random punch for punchnum in range(25): n = random.randint(0, len(list)-1) i = list[n] matrix[round((i-i%5)/5)][round(i%5)] = 1 list.pop(n) #check bingo for x in range(5): for y in range(5): checkbingo = checkbingo + (matrix[x][y]) if checkbingo == 5: bingo = 1 checkbingo = 0 if bingo == 0: for y in range(5): for x in range(5): checkbingo = checkbingo + (matrix[x][y]) if checkbingo == 5: bingo = 1 checkbingo = 0 print(punchnum," = ", bingo) print("basematrix = ", basematrix) matrix = basematrix print("matrix = ",matrix) list = baselist RE: how can a variable change if I haven't changed it? - bowlofred - Apr-07-2021 First, list and iter are names of classes in python. You shouldn't use them as variable names or you hide the ability to use the class namespaces.You don't have anything named oldmatrix in your code, but I can guess what you've done is assumed that assigning a list copies the data rather than just a reference to it. (Please put your code in "python" tags so that the indentation is preserved).I've made some other code to show how this can affect you and one way to avoid it. baselist = [0, 0, 0, 0] working_list = baselist # copies the object, not the elements inside working_list[2] = "XX" print(f"{working_list=}") print(f"{baselist=}") print() # Note "baselist" has changed without explicitly doing so because it is the same object # as working_list. baselist = [0, 0, 0, 0] working_list = baselist.copy() # This is a copy and the two objects are different working_list[2] = "XX" # doesn't change baselist now. print(f"{working_list=}") print(f"{baselist=}")
RE: how can a variable change if I haven't changed it? - jefsummers - Apr-07-2021 Great youtube from PyCon that explains this behavior, mutable and immutable values, etc. Pycon 2015 Ned Batchelder RE: how can a variable change if I haven't changed it? - niminim - Apr-07-2021 (Apr-07-2021, 05:14 PM)bowlofred Wrote: First, First, thank you, you are super helpful. I indeed meant basematrix. I made some changes according to your advice. Still doesn't;t work, basematrix get changed. I'm sure I'm doing a foolish mistake but I can't find it, # Online Python compiler (interpreter) to run Python online. # Write Python 3 code in this online editor and run it. import random print("Hello world") bingo = 0 checkbingo = 0 basematrix = [[0,0,0,0,0],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0]] matrix = [[0,0,0,0,0],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0]] baselist = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24] punchlist = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24] for runningtimes in range(2): print("runningtimes =", runningtimes) print("basematrix = ", basematrix) print("matrix = ",matrix) #random punch for punchnum in range(25): n = random.randint(0, len(punchlist)-1) i = punchlist[n] matrix[round((i-i%5)/5)][round(i%5)] = 1 punchlist.pop(n) #check bingo for x in range(5): for y in range(5): checkbingo = checkbingo + (matrix[x][y]) if checkbingo == 5: bingo = 1 checkbingo = 0 if bingo == 0: for y in range(5): for x in range(5): checkbingo = checkbingo + (matrix[x][y]) if checkbingo == 5: bingo = 1 checkbingo = 0 print(punchnum," = ", bingo) print("basematrix = ", basematrix) matrix = basematrix.copy() print("matrix = ",matrix) punchlist = baselist.copy() print("punchlist =", punchlist) RE: how can a variable change if I haven't changed it? - deanhystad - Apr-07-2021 You need to do a deep copy import copy a = [[1, 1], [2, 2]] b = a.copy() print('Copy') for x, y in zip(a, b): print(x, y, id(x), id(y)) print('\nDeep Copy') b = copy.deepcopy(a) for x, y in zip(a, b): print(x, y, id(x), id(y)) When you copy a list of lists the copy is a new list that contains lists from the original. To create copies of the contents you should use deepcopy from the copy library. Notice that the object ID's match when doing b = a.copy(), but when doing b = copy.deepcopy(a), new lists are created for the copy.
RE: how can a variable change if I haven't changed it? - niminim - Apr-07-2021 (Apr-07-2021, 06:33 PM)deanhystad Wrote: You need to do a deep copy Thanks pal, you've solved my problem and taught me a lesson. |