Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between LIST.append(1) and LIST = LIST + [1] (Python)

When I execute (I'm using the interactive shell) these statements I get this:

L=[1,2,3]
K=L

L.append(4)

L
[1,2,3,4]
K
[1,2,3,4]

But when I do exactly the same thing replacing L.append(4) with L=L+[4] I get:

L
[1,2,3,4]
K
[1,2,3]

Is this some sort of reference thing? Why does this happen?

Another funny thing I noticed is that L+=[4] acts like .append, which is odd as I thought it would act like L = L + [4].

Clarification to all of this would be greatly appreciated.

Thanks

like image 346
aitee Avatar asked Sep 03 '10 18:09

aitee


3 Answers

L.append(4)

This adds an element on to the end of the existing list L.

L += [4]

The += operator invokes the magic __iadd__() method. It turns out list overrides the __iadd__() method and makes it equivalent to extend() which, like append(), adds elements directly onto an existing list.

L = L + [4]

L + [4] generates a new list which is equal to L with 4 added to the end. This new list is then assigned back to L. Because you've created a new list object, K is unchanged by this assignment.

We can use id() to identify when a new object reference is created:

>>> L = [1, 2, 3]
>>> id(L)
152678284
>>> L.append(4)
>>> id(L)
152678284

>>> L = [1, 2, 3]
>>> id(L)
152680524
>>> L = L + [4]
>>> id(L)
152678316
like image 169
John Kugelman Avatar answered Oct 21 '22 07:10

John Kugelman


If you are curious about the bytecodes:

>>> def L_app( ):
...     L.append( 4 )
...
>>> def L_add( ):
...     L = L + [ 4 ]
...
>>> def L_add_inplace( ):
...     L += [ 4 ]
...
>>> dis.dis( L_app )
  2           0 LOAD_GLOBAL              0 (L)
              3 LOAD_ATTR                1 (append)
              6 LOAD_CONST               1 (4)
              9 CALL_FUNCTION            1
             12 POP_TOP
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE
>>> dis.dis( L_add )
  2           0 LOAD_FAST                0 (L)
              3 LOAD_CONST               1 (4)
              6 BUILD_LIST               1
              9 BINARY_ADD
             10 STORE_FAST               0 (L)
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE
>>> dis.dis( L_add_inplace )
  2           0 LOAD_FAST                0 (L)
              3 LOAD_CONST               1 (4)
              6 BUILD_LIST               1
              9 INPLACE_ADD
             10 STORE_FAST               0 (L)
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE
like image 27
Katriel Avatar answered Oct 21 '22 06:10

Katriel


With append you're modifying the list directly. With L=L+[4], you're making a copy of the original L and adding a new element, then assigning that result back to L and breaking its equivalence to K.

I'm not sure about the behavior of +=.

like image 45
Mark Ransom Avatar answered Oct 21 '22 07:10

Mark Ransom