How to create a new data object in memory, rather than pointing to one? (in Python 3)
Question: As an illustration of my question, say I want to swap two elements in an
array:

    
    
    # Array Integer Integer -> Array
    # I want to swap the values at locations i1 and i2. 
    # I want to return the array with values swapped.
    def swap(A, i1, i2):
        newA = A
        newA[i1] = A[i2]
        newA[i2] = A[i1]
        return newA
    

Run this code, and an array is returned with only one value changed:

    
    
    > testArray = [1, 2, 3, 4]
    > swap(testArray, 0, 1)
    [2, 2, 3, 4]
    

Also, if I now check what testArray is (I want it to still be [1, 2, 3, 4]):

    
    
    > testArray
    [2, 2, 3, 4]
    

So my questions are:

  1. I guess newA = A uses a pointer to A. I'm used to programming in a style where I return a new data structure each time. I'd like to create a whole new array, newA, which just has the same values as A. Then I can let garbage collection take care of newA later. Can I do this in python?

  2. What is newA = A really doing? 

  3. Why would someone create a new variable (like newA) to point to the old one (A)? Why wouldn't they just mutate A directly? 

  4. And why does the syntax behave differently for atomic data? 

i.e.

    
    
    a = 1
    b = a # this same syntax doesn't seem to be a pointer.
    b = 2
    > a
    1
    


Answer: If it is list of integers then you can do:

    
    
    def swap(A, i1, i2):
    
        temp = A[i1]
        A[i1] = A[i2]
        A[i2] = temp
    
        return A
    

or more pythonic way

    
    
    def swap(A, i1, i2):
    
        A[i1], A[i2] = A[i2], A[i1]
    
        return A
    

-
    
    
     newA = A
    

this create "alias" - both variables use the same list in memory. When you
change value in A then you change value in newA too.

see visualization on PythonTutor.com (it is long link with Python code)

[http://pythontutor.com/visualize.html#code=A+%3D+%5B1,+2,+3,+4%5D%0A%0AnewA+%3D+A&mode=display&origin=opt-
frontend.js&cumulative=false&heapPrimitives=false&textReferences=false&py=2&rawInputLstJSON=%5B%5D&curInstr=2](http://pythontutor.com/visualize.html#code=A+%3D+%5B1,+2,+3,+4%5D%0A%0AnewA+%3D+A&mode=display&origin=opt-
frontend.js&cumulative=false&heapPrimitives=false&textReferences=false&py=2&rawInputLstJSON=%5B%5D&curInstr=2)

-

To create copy you can use `slicing`

    
    
    newA = A[:] # python 2 & 3
    

or

    
    
    import copy
    
    newA = copy.copy(A)
    newA = copy.deepcopy(A)
    

or on Python 3

    
    
    newA = A.copy()
    

-

`integers` and `float` are kept in variable but other objects are too big to
keep it in variable so python keeps only reference/pointer to memory with this
big object. Sometimes it is better to send reference (to function or class)
than clone all data and send it.

    
    
     a = 1
     b = a # copy value
    
     a = [1,2,3] # big object - variable keeps reference/pointer
     b = a # copy reference
    

