0

I am a relative python novice. I have a simple function here that takes in a list and removes an element of the list. However, I noticed that the function actually alters the list outside of the function. For example,

def test(lista):
    lista.remove(1)
    return(lista)

def main():
    a = [1,2,3]

    print(a)

    x = test(lista=a)

    print(a)

It turns out that the first call to print(a), I get [1, 2, 3] as expected, but the second call to print(a), I get [2, 3] which doesn't quite make sense to me because I'm not sure why the function test would remove the element from a. I understand that I pass a in as a parameter, but I'm not sure why lista.remove(1) would remove the element 1 from both a and lista.

Thanks!

The Room
  • 758
  • 1
  • 9
  • 22
Vincent
  • 7,808
  • 13
  • 49
  • 63
  • `lista` is just another name for the argument that is passed. That is, `lista` is just a synonym for `a`. They are the same object. – zondo Feb 27 '16 at 03:40
  • 1
    You passed in a list and then modified it... its pretty straight forward. If you want to keep the original list, make a copy for the function. – tdelaney Feb 27 '16 at 03:42
  • Is it a good idea to have a function that overwrites the list that you passed in instead of returning a new one? – ml-moron Feb 27 '16 at 03:46
  • 1
    I recommend reading Ned Batchelder's [Facts and myths about Python names and values](http://nedbatchelder.com/text/names.html). It's one of the best explanations of how stuff like this works. – user2357112 Feb 27 '16 at 04:14

1 Answers1

0

Python objects are passed-by-object-reference to functions (ruby calls this pass-by-reference but it's different than C++ pass-by-reference). This means that the argument you assign to lista is the original object a, simply with a new named reference object to the same data.

If you instead copied the list it would not affect the original

x = test(lista=list(a))
Pyrce
  • 8,296
  • 3
  • 31
  • 46
  • 2
    "Python objects are passed by reference to functions" - while the thing that is passed to the function is a reference, "pass-by-reference" refers to a specific, different parameter passing model. In pass-by-reference, `lista` would be an alias for the caller's variable, rather than both variables referring to a shared object, and assignments to `lista` would affect the caller's variable. – user2357112 Feb 27 '16 at 04:20
  • @user2357112 I was being a bit liberal with the terminology as Ruby calls it pass by reference for the same operation. I updated to clarify that it's not quite the same as traditional pass by reference. – Pyrce Feb 27 '16 at 19:09
  • Do you have a source for Ruby calling this pass by reference? When I google `Ruby pass by reference`, I get zero sources calling it pass by reference. The closest is "pass by value where the value is a reference", like the Java guys call it. – user2357112 Feb 27 '16 at 19:38
  • http://stupidpythonideas.blogspot.com/2013/11/does-python-pass-by-value-or-by.html but http://robertheaton.com/2014/07/22/is-ruby-pass-by-reference-or-pass-by-value/ calls it Pass-reference-by-value and the O'Reilly book, The Ruby Programming Language calls it out as "arguments are passed by value rather than by reference, but that the values passed are object references". All 3 sources call out that pass-by-reference is a confusing term and that it doesn't translate well from C++ to ruby's (and by corollary python's) object abstaction model – Pyrce Feb 27 '16 at 21:50