Python: Local copy of array / list in functions

1.2k views Asked by At

In the function "change(par)", does "par[:]" already make a local copy? It works for the list, why doesn't it work for the array?

import numpy

def change(par):

    copy = par[:]
    copy[0] = 123


def main():

   L = [0, 0, 0]
   print '\nL before: ' + str(L)
   change(L)
   print 'L after: ' + str(L)

   A = numpy.zeros((1, 3))
   print '\nA before: ' + str(A)
   change(A[0])
   print 'A after: ' + str(A)


if __name__ == '__main__':
    main()

Output:

L before: [0, 0, 0]
L after: [0, 0, 0]

A before: [[ 0.  0.  0.]]
A after: [[ 123.    0.    0.]]

UPDATE

Thank you for pointing out "par[:]" is a shallow copy, and it doesn't work for array.

So how does "shallow copy" work in case of array structures? In the case of list, "shallow copy" copies the values, but when it turns into array, "shallow copy" just copies the references not the values?

How does "[:]" distinguish when to copy values and when to just copy references?

2

There are 2 answers

0
Samuel Yvon On

When you "copy" a numpy array the way you do, you don't really copy it. You select a range of elements from it (in your case, all of them). That range is linked to the actual values of the array. Think of it as a "window", you see a "limited" range, but you don't actually have a copy of it, you do your operations through that "window".

In the case of a python list, you indeed clone it.

If you want to clone the numpy array, you can use the copy method : (numpy doc)

0
Skycc On

As the comment mention, you are doing shallow copy by syntax [:], it only works for single dimensional list

You can make use of deepcopy function from copy module for cloning multi dimensional list/array

import copy
def change(par):
    copy = copy.deepcopy(par)
    copy[0] = 123