I'd like to implement a function that allows the values of its arguments to be reallocated 'in place'.
As an example, a function that will increment argument x and decrement argument y. (This is just a simple example for illustration - the motivation is that X and Y are in fact single elements of a large dataframe; their expressions are unwieldy; and this operation will undergo many iterations.)
def incdec(x,y,d):
x += d
y -= d
Ideally this would be run as:
X = 5; Y = 7; d = 2
incdec(X,Y,d)
to find that the values are now X = 7 and Y = 5. But of course it doesn't work like that - I wondered why?
Mutable and immutable typesSome values in python can be modified, and some cannot. This does not ever mean that we can't change the value of a variable – but if a variable contains a value of an immutable type, we can only assign it a new value. We cannot alter the existing value in any way.
The word "change" is ambiguous in Python: we have two distinct types of "change" in Python. We can "change" a variable by changing which object that variable is pointing to. We do that through an assignment statement. We can also "change" an actual object through a mutation.
Pass by reference means that you have to pass the function(reference) to a variable which refers that the variable already exists in memory. Here, the variable( the bucket) is passed into the function directly. The variable acts as a Package that comes with its contents(the objects).
Python global keyword is used to change the scope of variables. By default variables inside the function has local scope. Means you can't use it outside the function. Simple use global keyword to read and write a global variable inside a function.
In Python When a function with arguments is called, copies of the values of the arguments are stored in local variables. Indeed when you write
def incdec(x,y,d):
x += d
y -= d
the only thing that changes are the x and y that are IN THE function indec. But at the end of the function local variables are lost. To obtain what you want you should remember what the function did. To remember those values AFTER the function you should re-assigne x and y like this:
def incdec(x,y,d):
x += d
y -= d
return (x,y)
# and then
X = 5; Y = 7; d = 2
X,Y = incdec(X,Y,d)
this works because X,Y are of type int. What you also could do is using a list to have a direct access to the variables you want to change.
def incdec(list_1,d):
list_1[0] += d
list_1[1] -= d
#no return needed
# and then
X = 5; Y = 7; d = 2
new_list = [X, Y]
incdec(new_list,d) #the list has changed but not X and Y
Don t get me wrong, the arguments passed are still a copy as I said earlier but when you copy a list, only references are copied, but those are still looking at the same object. Here's a demo:
number = 5
list_a = [number] #we copy the value of number
print (list_a[0]) # output is 5
list_b = list_a # we copy all references os list_a into list_b
print(list_b[0]) # output is 5
list_a[0]=99
print(list_b[0]) # output is 99
print(number) # output is 5
as you can see list_a[0] and list_b[0]
is one same object but number is a different one
That s because we copied the value of number
and not the reference.
I recommend you to use the first solution.
I hope this helped.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With