I am a bit confused about, changing (mutating or appending) variables from within functions.
For reference, i found this question about functions that mutate the argument. which describes doing just that on an array:
def add_thing(a):
a.append(2)
my_a = [1]
append_two(my_a)
my_a
>>> [1,2]
and we get the same results using a += [2]
However, if we try the same thing with a string, or an integer:
def add_world (s):
s += " world"
my_str = "hello"
add_world(my_str)
my_str
>>> "hello"
It doesn't change, and the same goes for integers, like:
def add_one(i):
i += 1
x = 1
add_one(x)
x
>>> 1
My question is:
How should I recognize which objects I can mutate in a function like an array, and which ones I need to directly assign?
why is the += operator not working as I'd expect? I was fairly sure that it was short hand for my_var = my_var + thing, which aught to work just fine within a function.
-
1possible duplicate of How do I pass a variable by reference?Ruggero Turra– Ruggero Turra2015年09月18日 17:19:46 +00:00Commented Sep 18, 2015 at 17:19
-
1possible duplicate of Function changes list values and not variable values in PythonChad S.– Chad S.2015年09月18日 17:20:51 +00:00Commented Sep 18, 2015 at 17:20
-
1Read this carefully, preferably twice. It will clear some things up for you. robertheaton.com/2014/02/09/…Rick– Rick2015年09月18日 17:27:18 +00:00Commented Sep 18, 2015 at 17:27
-
Thanks all, I'm was pretty sure that this is well covered territory, I just couldn't dig up anything specific.Lundy– Lundy2015年09月18日 17:40:56 +00:00Commented Sep 18, 2015 at 17:40
2 Answers 2
You have to look at the documentation. Generally: numbers, strings and
tuples are immutable.Regarding specific methods, there is a general rule also: if the method returns something then it doesn't modify the argument. Methods that modify the argument return
None.a += bis equivalent toa = a + bifais immutable. Ifais mutable then using+=will mutate the object. Basically+=is just a method call (to__iadd__). In the case of immutable objects the method returns a new object and doesn't mutate the original value, for mutable object the object is mutate and it returns itself.
Comments
How should I recognize which objects I can mutate in a function like an array, and which ones I need to directly assign?
You need to know what kinds of objects you're using and read the documentation for those objects to know which operations, if any, mutate them. Unfortunately in the case of list this is not documented in the most accessible way. The closest thing is this which says:
An augmented assignment expression like
x += 1can be rewritten asx = x + 1to achieve a similar, but not exactly equal effect. In the augmented version, x is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.
Since lists are mutable, that means the in-place operation is possible.
why is the += operator not working as I'd expect? I was fairly sure that it was short hand for my_var = my_var + thing, which aught to work just fine within a function.
As the quote above shows, a += b is not quite the same as a = a + b. The difference is that the object a has the opportunity to define special behavior for a += b that may be different from the behavior for a + b. Lists do this so that += works in-place.
Comments
Explore related questions
See similar questions with these tags.