20

To understand why I was getting an error in a program , in which I tried to find the "minor" of a determinant, I wrote a simpler program because my variables were messed up. This function below takes in a 2 * 2 matrix as an input, and returns a list containing its rows (pointless and inefficient, I know, but I'm trying to understand the theory behind this).

def alpha(A):   #where A will be a 2 * 2 matrix
    B = A       #the only purpose of B is to store the initial value of A, to retrieve it later
    mylist = []
    for i in range(2):
        for j in range(2):
            del A[i][j]
        array.append(A)
        A = B
    return mylist

However, here it seems that B is assigned the value of A dynamically, in the sense that I'm not able to store the initial value of A in B to use it later. Why is that?

Nikaido
  • 4,443
  • 5
  • 30
  • 47
Sphener
  • 313
  • 1
  • 2
  • 7
  • 2
    Should `array.append(A)` really be `mylist.append(A)`? If not, where is `array` defined? – CDspace Nov 02 '16 at 14:34
  • 1
    I'm afraid you copied the array.append(A) from documentation without considering that "array" is the actual array you want append to, i.e. the variable corresponding to that array, not an "array" package. Sorry if I missed sometihng? – yohann.martineau Nov 02 '16 at 14:34
  • [Python pass by reference](http://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/) – Daniel Nov 02 '16 at 14:38
  • for a pretty visualization, compare [one] with [two]. [1]: http://pythontutor.com/visualize.html#code=a%20%3D%20%5B1,2,3%5D%0Ab%20%3D%20a&cumulative=true&curInstr=2&heapPrimitives=true&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false [2]: http://pythontutor.com/visualize.html#code=a%20%3D%20%5B1,2,3%5D%0Ab%20%3D%20a%5B%3A%5D&cumulative=true&curInstr=2&heapPrimitives=true&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false – Chris_Rands Nov 02 '16 at 15:12

3 Answers3

35

Because python passes lists by reference

This means that when you write "b=a" you're saying that a and b are the same object, and that when you change b you change also a, and viceversa

A way to copy a list by value:

new_list = old_list[:]

If the list contains objects and you want to copy them as well, use generic copy.deepcopy():

import copy
new_list = copy.deepcopy(old_list)
Nikaido
  • 4,443
  • 5
  • 30
  • 47
4

Since Python passes list by reference, A and B are the same objects. When you modify B you are also modifying A. This behavior can be demonstrated in a simple example:

>>> A = [1, 2, 3]
>>> def change(l):
...     b = l
...     b.append(4)
... 
>>> A
[1, 2, 3]
>>> change(A)
>>> A
[1, 2, 3, 4]
>>> 

If you need a copy of A use slice notation:

B = A[:]

Christian Dean
  • 22,138
  • 7
  • 54
  • 87
1

A looks like a reference type, not a value type. Reference types are not copied on assignment (unlike e.g. R). You can use copy.copy to make a deep copy of an element

Christian Sauer
  • 10,351
  • 10
  • 53
  • 85