Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passed argument/parameter in function is still being changed after removing the reference/alias

Tags:

python

I've spent the last 2 hours on this and I've probably read every question on here relating to variables being passed to functions. My issue is the common one of the parameter/argument being affected by changes made inside the function, even though I have removed the reference/alias by using variable_cloned = variable[:] in the function to copy the contents across without the reference.

Here is the code:

def add_column(m):    
    #this should "clone" m without passing any reference on    
    m_cloned = m[:]
    for index, element in enumerate(m_cloned):
        # parameter m can be seen changing along with m_cloned even
        # though 'm' is not touched during this function except to 
        # pass it's contents onto 'm_cloned'        
        print "This is parameter 'm' during the for loop...", m
        m_cloned[index] += [0]
    print "This is parameter 'm' at end of for loop...", m    
    print "This is variable 'm_cloned' at end of for loop...", m_cloned
    print "m_cloned is m =", m_cloned is m, "implies there is no reference"
    return m_cloned

matrix = [[3, 2], [5, 1], [4, 7]]
print "\n"
print "Variable 'matrix' before function:", matrix
print "\n"
add_column(matrix)
print "\n"
print "Variable 'matrix' after function:", matrix

What I'm noticing is that the parameter 'm' in the function is changing as if is an alias of m_cloned - but as far as I can tell I have removed the alias with the first line of the function. Everywhere else I have looked online seems to suggest that this line will make sure there is no reference to parameter - but it's not working.

I'm sure I must have made a simple mistake but after 2 hours I don't think I'm going to find it.

like image 810
FiveAlive Avatar asked Jan 07 '12 23:01

FiveAlive


People also ask

Does passing by reference change the value?

Pass-by-reference means to pass the reference of an argument in the calling function to the corresponding formal parameter of the called function. The called function can modify the value of the argument by using its reference passed in.

What happens when we pass arguments in a function by reference?

The call by reference method of passing arguments to a function copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. It means the changes made to the parameter affect the passed argument.

How do you pass arguments to alias in bash?

Solution 1. You can replace $@ with $1 if you only want the first argument. This creates a temporary function f , which is passed the arguments (note that f is called at the very end). The unset -f removes the function definition as the alias is executed so it doesn't hang around afterwards.

Can alias take arguments bash?

Bash users need to understand that alias cannot take arguments and parameters. But we can use functions to take arguments and parameters while using alias commands.


1 Answers

It looks like you need a deepcopy, instead of a shallow copy, which is what [:] gives you:

from copy import deepcopy
list2 = deepcopy(list1)

Here's a longer example comparing the two types of copy:

from copy import deepcopy

list1 = [[1], [1]]
list2 = list1[:]   # while id(list1) != id(list2), it's items have the same id()s
list3 = deepcopy(list1)

list1[0] += [3]

print list1
print list2
print list3

Outputs:

[[1, 3], [1]]  # list1
[[1, 3], [1]]  # list2
[[1], [1]]     # list3 - unaffected by reference-madness
like image 108
Adam Wagner Avatar answered Oct 09 '22 12:10

Adam Wagner