This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 6 years ago.
Much has been written about python pass-by-object-reference. But it is confusing to read threads like this or this.
In those threads, some say mutability is important, while others say that mutable or immutable objects are handled the same way.
I have a simple question, why are the contents of a not modified in the first snippet of code and modified in the second? According to this explanation of pass-by-object-reference, shouldn't the contents of the reference be modified in both cases?
def fn(b):
b += 1
a = 2
fn(a)
print(a)
def fn(b):
b += [4]
a = [2]
fn(a)
print(a)
shouldn't the contents of the reference be modified in both cases?
No, since int objects are immutable.
You don't even need functions to demonstrate this.
Consider the following:
a = 1
print(id(a))
a += 1
print(id(a))
>> 496418832
496418848
We are obviously getting a new object.
Compare to:
a = [1]
print(id(a))
a += [2]
print(id(a))
>> 36641608
36641608
Note a is still referencing the same object in this case.
Related
This question already has answers here:
Why does += behave unexpectedly on lists?
(9 answers)
Closed 1 year ago.
I'm trying to learn coding through some tutorials and encountered something curious as I'm going over operators. The basic ones I get, but some others (like *= here) throw me off.
a = 1
b = a
a *= 2
print(a)
print(b)
Output
2
1
But when a is an array, this happens:
a = np.array([1, 2, 3, 3, 5, 5])
b = a
a *= 2
print(a)
print(b)
Output
[2 4 6 6 10 10]
[2 4 6 6 10 10]
Any insight as to why this happens? I can't really find much about it. The only thing I came across was "coercion rules"; does the second instance happen because a is being assigned to an array but then to an integer? Or is it a matter of the print statement order?
It's probably trivial but I'm just curious, thanks!
The Simple answer to your question is,
There are two kinds of objects in Python: Mutable objects and Immutable objects. The value of a mutable object can be modified in place after it’s creation, while the value of an immutable object cannot be changed.
Immutable(Not Modifiable) Object: int, float, long, complex, string tuple, bool
Mutable(Modifiable) Object: list, dict, set, byte array, user-defined classes.
So,here in your case firstly a and b are immutable objects as it belongs to class int in python,"b=a" means b is pointing towards a address,and as you update value of a to a*=2, the value is store on new memory location, but b is still pointing towards older address, thats why b is not showing changed value of a.
For more understanding of memory management in python, please read this blog, thankyou :)
https://medium.com/#tyastropheus/tricky-python-i-memory-management-for-mutable-immutable-objects-21507d1e5b95
This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 3 years ago.
a=[1] # here is a comment to the right
print("as expected, a=", a)
b=a
print("as expected, b=", b)
a[0]=2
print("as expected, now a=", a)
print("NOT EXPECTED TO CHANGE now b=", b)
lists are mutable ... both a and b point to the same list, so changing a will also change b
if you do not want this behaviour assign a copy of a to b
b = a[:]
if you had used an immutable datatype (like a string or number) when you change it it assigns a completely new variable to b and works ... but mutable datatypes wont work like this
In python (as in many languages, with the notable exception of C/C++), names are references to values. When you write a = b, you make a refer to the same value as b, you don't copy its contents.
Use b = list(a) to create a copy (or see deepcopy for more complex objects)
This question already has answers here:
Why does += behave unexpectedly on lists?
(9 answers)
Closed 6 years ago.
I don't understand why these functions give different results; I thought that s+= and s=s+ were equivalent:
def foo(s):
s += ['hi']
def foo2(s):
s = s + ['hi']
But the first modifies the list s and the second does not. Could someone help me clarifying this?
x+= y is same as x = x + y only for immutable types. For mutable types, the option exists to alter the object in-place. So for lists, += is the same as list.extend() followed by a re-bind of the name.
Read: Augmented Assignment Statements and Why does += behave unexpectedly on lists? for more information.
Use list.append because if you say s = s +['hi'] then s just point to another object, but if you use .append() then the same list is being changed
This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 7 years ago.
In detail, my question is this:
Given the following code,
x = 10
def func(x):
x = x+1
def main():
print(x)
func(x)
print(x)
if __name__ == '__main__':
main()
On running this I get:
10
10
Does this mean that Python does not pass values by reference?
And I did check through the other question of the sort, and most(if not all) included analogies of lists or other such examples.
Is it possible to explain this in simple terms, like just a simple integer?
Ps. I am a beginner to coding.
Thanks
If you are coming from a background such as C or C++, which I did, this can be maddening until you figure it out.
Python has names, not variables, and names are bound to objects. Effectively, you can think of all 'variables' or names, as being pointers to python objects.
In python, integers, floats, and strings are immutable. So when you do the following:
x = 10
x = x + 1
You are first binding the name x to the integer 10, then when you evaluate x + 1 you get a new object 11 and then you bind x to that object. Your x inside the function body is local to the function, and when you bind it to 11, the global x remains bound to 10.
If you were to pass a list to the function, and append something to the list, that list would be modified. A list in python is a mutable object. All names bound to the list would refer to the modified list.
As a result, when you pass mutable objects it may seem as if you are passing by reference, and when you pass immutable objects it may seem like you are passing by value.
This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 7 years ago.
So basically i've observed that in python3 if i do something like
a = 5
def addFive(x):
x+=5
return x
print(addFive(a),a)
The output will be "10 5" since a is not changed by the function.
However the same does not happen for lists:
a = [1,2,3]
def b(x):
z = x
z.append(10)
b(a)
print(a)
When i run the function it changes the actual list.
Now to my Question: Why does this happen, where can i read up more about this(Honestly have no idea how to word my google search) and how can i avoid this. Please feel free to redirect me to other articles as this could be a common problem but I honestly couldn't find anything similar.
Thanks in advance :)
Use the copy module.
import copy
a = [1,2,3]
def b(x):
z = copy.deepcopy(x)
z.append(10)
return z
b(a)
print(a)
This prints
[1, 2, 3, 10]
[1, 2, 3]
Each element in a Python list is a location in memory, so when you modify an element, you're actually modifying that reference in memory. So if you're familiar with C++, passing a list into a function in Python, is similar in concept to passing by reference.