0
list4=[7,8]
def proc3(mylist):
    mylist+=[9]


print list4
proc3(list4)
print list4

Why does this code produce the answers [7,8] and [7,8,9]? I expected [7,8] and [7,8]. Doesn't mylist+=[9] concatenate the number 9 and create a new list as a local variable only? Why does the "print list4" after the running proc3(list4), but outside the procedure, not result in the original list? I must be missing something obvious here. Thanks in advance for any help.

user3150100
  • 45
  • 1
  • 4
  • Even though you are correct that `proc3` has a different reference to the `list` object than the one in your global namespace, the `+=` operator *mutates* the list. You're altering the object itself, it doesn't matter that you're doing it with a second reference. – roippi Jan 03 '14 at 05:12
  • Check this answer which explains everything you need to know for pass by value and pass by reference in python http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference – Aks Jan 03 '14 at 05:12

3 Answers3

3

+= does not return a new list object. Instead, it modifies the original list object in-place.

In other words, this line inside proc3:

mylist+=[9]

is modifying the list object referenced by mylist. As a result, it is no longer [7, 8] but [7, 8, 9].

  • So does the += operator act similarly to mylist.append(9) which mutates the list? I thought it was the same as mylist=mylist+[9], which points to a new concatenated list... – user3150100 Jan 03 '14 at 05:16
  • One more thing. It's not exactly the same as .append, because mylist.append([9,10]) creates [7,8,[9,10]], whereas mylist+=[9,10] creates [7,8,9,10], right? Thanks for the help, this is quite subtle for such a simple operation :-). – user3150100 Jan 03 '14 at 05:59
  • @iCodez Actually, `+=` works exactly like `mylist.extend`. If it were like `mylist.append` then `mylist += [9]` would result in `[7, 8, [9]]`. It's an important distinction, especially if someone were to do something like `mylist += 'hello'` and would get the unexpected result of `[7, 8, 'h', 'e', 'l', 'l', 'o']` – SethMMorton Jan 03 '14 at 07:18
  • @user3150100 Ha, yes, I should have read your comment first. `+=` is a shortcut for `list.extend`. – SethMMorton Jan 03 '14 at 07:19
  • @SethMMorton - Yes, my mistake (I'll remove my previous comment so that there is no future confusion :). When the OP said `list.append`, I focused on it being an in-place operation like `+=`. But `list.extend` is a lot more accurate. –  Jan 03 '14 at 14:29
1

Quoting this answer in another post:

Everything is a reference in Python. If you wish to avoid that behavior you would have to create a new copy of the original with list(). If the list contains more references, you'd need to use deepcopy():

Let's:

list4 = [7, 8]
def proc3(mylist):
    print id(list4)
    mylist += [9]
    print id(list4)


print list4
print id(list4)
proc3(list4)
print id(list4)
print list4

This would print:

[7, 8]
36533384
36533384
36533384
36533384
[7, 8, 9]

So as you can see, it's the same list in every moment.

Community
  • 1
  • 1
Christian Tapia
  • 33,620
  • 7
  • 56
  • 73
0

the += operator modifies the object. Notice that

x += y

is much different from

x = x + y

(check with your test code)

Emanuele Paolini
  • 9,912
  • 3
  • 38
  • 64