Skip to content
Advertisement

In Python, why my variable StartingU get updated when I only update the variable AverageU in my for loops? What is wrong with the code?

The purpose is to calculate the average value (AverageU) from a starting array (StartingU)

import numpy as np

AverageU=np.zeros((3,3))
StartingU=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

size=2
stride=1
m, n = StartingU.shape

print("Before averaging:")
print("AverageU=", AverageU)
print("StartingU=", StartingU)

AverageU = StartingU

The for loops that calculate the average values for AverageU

for i in range(0, m - size + 1, stride):
    for j in range(0, n - size + 1, stride):
        avg = np.sum(np.sum(AverageU[i:i + size, j:j + size])) / (size * size)
        for ii in range(i, i + size):
            for jj in range(j, j + size):
                AverageU[ii, jj] = avg
                #print("In for loop, StartingU=", StartingU)
     
print("After averaging:")
print("AverageU=", AverageU)
print("StartingU=", StartingU)

Output:

Before averaging:
AverageU= [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
StartingU= [[1 2 3]
 [4 5 6]
 [7 8 9]]
After averaging:
AverageU= [[3 3 3]
 [5 5 5]
 [5 5 5]]
StartingU= [[3 3 3]
 [5 5 5]
 [5 5 5]]

The problem is why StartingU gets updated? It should be unchanged

StartingU=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

Advertisement

Answer

AverageU changed since this code, not after for loop.

print("Before averaging:")
print("AverageU=", AverageU)
print("StartingU=", StartingU)

AverageU = StartingU  # since here, AverageU variable changed

print("AverageU=", AverageU)
print("StartingU=", StartingU)  # please check here again.

AverageU and StartingU are the same instances. You can check it with is function.

StartingU = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
AverageU = StartingU
print(StartingU is AverageU)  # True

You should make a new instance as the comment said.

StartingU = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

AverageU_new1 = StartingU[:]
AverageU_new2 = StartingU.copy()
print(StartingU is AverageU_new2)  # False
print(StartingU is AverageU_new1)  # False

AverageU = StartingU This code just makes another reference to the same object with a new name and this indicates the same memory. You can check the memory address of the variable with function id

You can compare like this.

copy_1 = StartingU
copy_2 = StartingU[:]
copy_3 = StartingU.copy()
print(id(StartingU), id(copy_1), id(copy_2), id(copy_3))

Notice

Copy with the colon is actually a shallow copy, it copies only the reference of the nested list.

6 People found this is helpful
Advertisement