Python Forum
how can a variable change if I haven't changed it?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
how can a variable change if I haven't changed it?
#1
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
Reply
#2
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=}")
Output:
working_list=[0, 0, 'XX', 0] baselist=[0, 0, 'XX', 0] working_list=[0, 0, 'XX', 0] baselist=[0, 0, 0, 0]
Reply
#3
Great youtube from PyCon that explains this behavior, mutable and immutable values, etc.

Pycon 2015 Ned Batchelder
Reply
#4
(Apr-07-2021, 05:14 PM)bowlofred Wrote: 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=}")
Output:
working_list=[0, 0, 'XX', 0] baselist=[0, 0, 'XX', 0] working_list=[0, 0, 'XX', 0] baselist=[0, 0, 0, 0]

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)
   
    
  
Reply
#5
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))
Output:
Copy [1, 1] [1, 1] 2858215123584 2858215123584 [2, 2] [2, 2] 2858215123072 2858215123072 Deep Copy [1, 1] [1, 1] 2858215123584 2858215122240 [2, 2] [2, 2] 2858215123072 2858215123520
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.
Reply
#6
(Apr-07-2021, 06:33 PM)deanhystad Wrote: 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))
Output:
Copy [1, 1] [1, 1] 2858215123584 2858215123584 [2, 2] [2, 2] 2858215123072 2858215123072 Deep Copy [1, 1] [1, 1] 2858215123584 2858215122240 [2, 2] [2, 2] 2858215123072 2858215123520
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.

Thanks pal, you've solved my problem and taught me a lesson.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Help with writing monitored data to mysql upon change of one particular variable donottrackmymetadata 3 172 7 hours ago
Last Post: deanhystad
  The behavior of tune model has changed Led_Zeppelin 5 4,423 Oct-21-2021, 06:52 PM
Last Post: jefsummers
  Change variable value during a while loop? penahuse 2 4,049 Nov-15-2020, 11:53 PM
Last Post: penahuse
  Change variable in an outside file ebolisa 5 2,622 Nov-11-2020, 04:41 AM
Last Post: ebolisa
  Change name of variable samuelbachorik 2 2,049 Aug-10-2020, 02:34 PM
Last Post: deanhystad
  Python - change variable type during program execution ple 1 2,369 Apr-12-2020, 08:43 AM
Last Post: buran
  I haven't a clue how to implement this logic 357mag 3 2,105 Apr-02-2020, 04:35 PM
Last Post: 357mag
  trying to change variable value with a def pythonbegginer 11 4,512 Mar-07-2020, 02:54 PM
Last Post: pythonbegginer
  RuntimeError: dictionary changed size during iteration Shreeniket987 3 3,724 Jun-01-2019, 01:22 PM
Last Post: buran
  my list is being changed ivinjjunior 15 5,670 May-29-2019, 02:54 PM
Last Post: ivinjjunior

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020