24

consider the following code:

>>> x = y = [1, 2, 3, 4]
>>> x += [4]
>>> x
[1, 2, 3, 4, 4]
>>> y
[1, 2, 3, 4, 4]

and then consider this:

>>> x = y = [1, 2, 3, 4]
>>> x = x + [4]
>>> x
[1, 2, 3, 4, 4]
>>> y
[1, 2, 3, 4]

Why is there a difference these two?

(And yes, I tried searching for this).

2
  • 4
    What is interesting about your last statement, is that this functionality is actually explained in the python docs: docs.python.org/reference/datamodel.html#object.__add__ (from searching about those terms) Commented Mar 19, 2012 at 7:27
  • 4
    @jdl: Yes I admit that I overlooked that. Commented Mar 19, 2012 at 7:29

3 Answers 3

35

__iadd__ mutates the list, whereas __add__ returns a new list, as demonstrated.

An expression of x += y first tries to call __iadd__ and, failing that, calls __add__ followed an assignment (see Sven's comment for a minor correction). Since list has __iadd__ then it does this little bit of mutation magic.

Sign up to request clarification or add additional context in comments.

5 Comments

If you want more details on this exact behavior and other insights into why Python is the way it is - I would highly recommend the python epiphanies talk from PyCon 2012. It will lead you to a lot of 'a ha!' moments.
@S Singh if you get your answer then please select the answer as accepted answer and complete the workflow. Otherwise this question will be shown as unanswered.
This answer is slightly misleading: The assignment is always performed, regardless whether __iadd__() or __add__() is called. list.__iadd__() simply returns self, though, so the assignment has no effect other than rendering the target name local to the current scope.
Also: __iadd__ works faster for lists (it changes object in-place instead of recreating one); it allows to append any iterable, a = [] a+=range(5) works for lists, and a = a + smth requires smth to be an instance of list
@thodnev "it allows to append any iterable" -- Wow, this must be the first time I see this sort of type coercion between built-in types in 13 years of doing Python. It is beyond me how anyone would think it'd be a good idea to make __add__ and __iadd__ behave so surprisingly differently.
5

The first mutates the list, and the second rebinds the name.

Comments

1

1)'+=' calls in-place add i.e iadd method. This method takes two parameters, but makes the change in-place, modifying the contents of the first parameter (i.e x is modified). Since both x and y point to same Pyobject they both are same.

2)Whereas x = x + [4] calls the add mehtod(x.add([4])) and instead of changing or adding values in-place it creates a new list to which a points to now and y still pointing to the old_list.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.