Augmented Assignment question

Robin Munn rmunn at pobox.com
Fri Jul 18 10:44:17 EDT 2003


Mel Wilson <mwilson at the-wire.com> wrote:
> In article <20030716132455272-0600 at news.xmission.com>,
> Adam Ruth <owski at hotmail.com> wrote:
>>As a side note, I wouldn't have thought that the augmented assign would
>>work the way you tried to use it.  I would have thought that it would be
>>analagous to the + operator and sequences:
>>
>>>	x = [1,2,3]
>>>	y = [1,2,3]
>>>	x + y
>>[1,2,3,1,2,3]
>>
>>So that the agumented form would be:
>>
>>>	x = [1,2,3]
>>>	x += [1,2,3]
>>[1,2,3,1,2,3]
>>
>>But I've never tried it before and didn't know that it didn't work with
>>sequences.  You learn something new every day.
> 
> It does:
> 
>>>> def multi():
> ...     return 4, 5, 6
> ...
>>>> a = (1,2,3)
>>>> a += multi()
>>>> a
> (1, 2, 3, 4, 5, 6)
> 
> It seems to be just that += refuses to work with tuple unpacking.

There's a subtle but very important difference between those two.

Lists:

>>> l = [1,2,3]
>>> id(l)
135706404
>>> l += [4,5,6]
>>> l
[1, 2, 3, 4, 5, 6]
>>> id(l)
135706404


Tuples:

>>> t = (1,2,3)
>>> id(t)
135480164
>>> t += (4,5,6)
>>> t
(1, 2, 3, 4, 5, 6)
>>> id(t)
135423036


Notice how the id remained the same in list augmented assignment, while
it changed in tuple augmented assignment. That's because in the first
example, l is not rebound; instead, the list object that l points to
gets extended. In the second example, t gets rebound to a *new* tuple
object. Another demonstration:

Lists:

>>> l = [1,2,3]
>>> id(l)
135704132
>>> l2 = l
>>> l += [4,5,6]
>>> id(l)
135704132
>>> l
[1, 2, 3, 4, 5, 6]
>>> l2
[1, 2, 3, 4, 5, 6]


Tuples:

>>> t = (1,2,3)
>>> id(t)
135480164
>>> t2 = t
>>> t += (4,5,6)
>>> id(t)
135423036
>>> t
(1, 2, 3, 4, 5, 6)
>>> t2
(1, 2, 3)


When you do augmented assignment on a tuple, a new object is created and
the name is rebound. In the example above, t2 still points to the old
object, which was not affected (since tuples are immutable).

One more example, with lists:

>>> l = [1,2,3]
>>> id(l)
135714564
>>> l2 = l
>>> l = l + [4,5,6]
>>> id(l)
135704372
>>> l
[1, 2, 3, 4, 5, 6]
>>> l2
[1, 2, 3]


This time we wrote "l = l + [4,5,6]" instead of "l += [4,5,6]". See the
difference?

This subtlety is why you should never, IMHO, try to apply augmented
assignment to a function parameter that's supposed to be a sequence. You
might intend for a tuple to be passed to your function, but what if
someone passes in a list instead? Be explicit: if you mean
"l.append(l2)", then write that. If you mean "l = l + l2", then write
that.

The only time I use augmented assignment is when I'm incrementing
integers, e.g. "count += 1".

-- 
Robin Munn <rmunn at pobox.com> | http://www.rmunn.com/ | PGP key 0x6AFB6838
-----------------------------+-----------------------+----------------------
"Remember, when it comes to commercial TV, the program is not the product.
YOU are the product, and the advertiser is the customer." - Mark W. Schumann




More information about the Python-list mailing list