1

While writing a recursive function in python, I noticed an interesting phenomenon. .append will change an input variable, but = creates a private instance variable in the function. For example, using equals does not affect a,

>>> def f(x):
        x=x[:-1]
>>> a=[1, 2, 3]
>>> f(a)
>>> a
[1, 2, 3]

while using append changes a.

>>> def g(x):
        x.remove(3)

>>> g(a)
>>> a
[1, 2]
>>> 

I assume this is because .remove edits the reference, while [:-1] creates a new list, but is there a reason why this occurs?

UnsignedByte
  • 849
  • 10
  • 29
  • 1
    run it on [pythontutor.com](http://pythontutor.com/) and you will see how references work - see blue arrows in visualisations. – furas Nov 29 '17 at 01:33
  • 3
    Ned explains everything your need to know [here](https://www.youtube.com/watch?v=_AEJHKGk9ns) perfectly. – timgeb Nov 29 '17 at 01:34
  • 1
    Already have answer `https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference` – Frank AK Nov 29 '17 at 01:35

2 Answers2

1

From Ned Batchelder - Facts and Myths about Python names and values - PyCon 2015:

Functions like x.append("something") and x.remove("something") mutate a value, and change their values. However, using x=x+["something"] or x=x[:-1] rebind a reference, and create a new value which the variable now points to.

Thanks to @timgeb for commenting the video!

UnsignedByte
  • 849
  • 10
  • 29
  • Note: A mutating slice assignment could be used to make it work (it would just be less efficient, since it would involve making a potentially huge temporary `list` just to remove one item), via `x[:] = x[:-1]`, because that's reassigning the range of values, not rebinding `x`. – ShadowRanger Nov 29 '17 at 02:08
0

In this code: .append is a function of x, so the x is the same instance; but, x = [1], the x will create a new instance. Try this:

def f(x):
    print(x, id(x))
    x = [1]
    print(x, id(x))
Tony
  • 21
  • 4