Problem in assigning arrays in Python

2

Hello, I do not know if this question has already been answered, but my problem is this:

When assigning a global variable to a local variable of a class, changing the value of the local variable also modifies the value of the global variable. Below I attach the code.

import numpy as np

x = np.zeros((3, 3))
x[1][1] = 1

class MyApp(QtWidgets.QMainWindow):

    def _func_1_(self):

        global x

        print("x[1][1] =", x[1][1])  # Primera Salida

        self.aux = x
        self.aux[1][1] = _func_2_(aux[1][1])

        print("x[1][1] =", x[1][1])  # Segunda Salida

    def _func_2_(self, value):

        return (value * 10)


    $ x[1][1] = 1
    $ x[1][1] = 10

As you can see in the output of the code, before performing the operation on the aux matrix the value of x [1] [1] = 1 , while after the operation that of x [1] [1] = 10 .

What can the code failure be?

Thank you very much.

    
asked by Marcelo S. 06.08.2017 в 16:31
source

2 answers

2

You only need to change the assignment:

self.aux = x

for

self.aux = x.copy()

Thus you change the reference to the global variable by a reference to a copy of the values of the matrix

    
answered by 06.08.2017 / 17:07
source
1

The problem with your code is that you are assuming that doing this self.aux = x copies the content of x to a new list, which is not true at least in Python (and in some other languages). You have to keep in mind that the variables are not the objects but a reference to them. That is, x is a variable that points to a list object is not the list itself. When you do self.aux = x what you do is create a new reference to the same object pointed to by x , so any operation on self.aux will affect the same object pointed to by x . This can be easily verified:

x = [1,2,3]
aux = x
print(id(x))
print(id(aux))
> 140621670367112
> 140621670367112

If you look at the id internal to which x points as aux is the same. The solution is to "copy" the original list and generate a new list object. There are several ways to do this, I recommend reading this . For example:

  • Using a "slice", which is also usually the fastest of the methods

    aux = x[:]
    
  • Using the constructor list

    aux = list(x)
    
  • Copying the list using copy()

    aux = x.copy()
    
  • For lists containing other objects use deepcopy()

    import copy
    lst2=copy.deepcopy(lst1)
    
  • Using list comprehension

    aux = [e for e in x]
    
  • "Extending" a new list

    aux = []; aux.extend(x)
    

Either way you choose the concept is the same: create a new object list from another list and assign the reference to the variable aux .

    
answered by 06.08.2017 в 22:55