Because a += b modifies the referand of a, whereas a = a + b creates a new object and binds it to a.
So for example: $ python Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01) [GCC 4.3.4 20090804 (release) 1] on cygwin Type "help", "copyright", "credits" or "license" for more information. >>> a = [1,2] >>> b = [3,4] >>> c = a >>> a += b >>> c [1, 2, 3, 4] >>> a = a + b >>> c [1, 2, 3, 4] >>> a [1, 2, 3, 4, 3, 4]
This probably shouldn't surprising except to C and C++ programmers...
I don't know about surprising, but I wouldn't expect it necessarily.
From my perspective it's non-intuitive to use += syntax for left hand sides that might not be mutable. And equally, expecting a = a + b to always bind a new object is no good, because not all left hand sides are bindable.
For example, a = a + b in JavaScript is mutation if a is a Number but is binding if a is a String.
Well, in Python everything is objects (semantically), so assignment with '=' is always binding, never mutation even for numbers. But I didn't give you the whole story above: += mutates only if the type permits (I don't know precisely how that's defined at the language level). Both numbers and strings are immutable, so for Python in both your examples a += b doesn't mutate, it does the same as a = a + b.
Python lists are mutable, and += behaves like extend().
I suppose really it's the combination of reseatable references with mutable objects that creates two possible meanings of +=, and hence the opportunity for surprise.
Comments 10
Reply
So for example:
$ python
Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01)
[GCC 4.3.4 20090804 (release) 1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2]
>>> b = [3,4]
>>> c = a
>>> a += b
>>> c
[1, 2, 3, 4]
>>> a = a + b
>>> c
[1, 2, 3, 4]
>>> a
[1, 2, 3, 4, 3, 4]
This probably shouldn't surprising except to C and C++ programmers...
Reply
From my perspective it's non-intuitive to use += syntax for left hand sides that might not be mutable. And equally, expecting a = a + b to always bind a new object is no good, because not all left hand sides are bindable.
For example, a = a + b in JavaScript is mutation if a is a Number but is binding if a is a String.
Reply
Python lists are mutable, and += behaves like extend().
I suppose really it's the combination of reseatable references with mutable objects that creates two possible meanings of +=, and hence the opportunity for surprise.
Reply
Leave a comment