Augument assignment versus regular assignment

Jim Segrave jes at nl.demon.net
Mon Jul 10 08:32:44 EDT 2006


In article <slrneb48qm.rg3.apardon at rcpc42.vub.ac.be>,
Antoon Pardon  <apardon at forel.vub.ac.be> wrote:
>On 2006-07-09, Fredrik Lundh <fredrik at pythonware.com> wrote:
>> Frank Millman wrote:
>>
>>> So it looks as if x +=  [] modifies the list in place, while x = x + []
>>> creates a new list.
>>
>> objects can override the += operator (by defining the __iadd__ method), 
>> and the list type maps __iadd__ to extend.  other containers may treat 
>> += differently, but in-place behaviour is recommended by the language
>> reference:
>>
>>    An augmented assignment expression like x += 1 can be rewritten as
>>    x = x + 1 to achieve a similar, but not exactly equal effect.  In
>>    the augmented version, x is only evaluated once. Also, when possible,
>>    the actual operation is performed in-place, meaning that rather than
>>    creating a new object and assigning that to the target, the old object
>>    is modified instead.
>
>What does it mean that x is only evaluated once.  I have an avltree module,
>with an interface much like a directory.  So I added print statements to
>__setitem__ and __getitem__ and then tried the following code.
>
>>>> from avltree import Tree
>>>> t=Tree()
>>>> t['a'] = 1
>__setitem__, key = a
>>>> t['a']
>__getitem__, key = a
>1
>>>> t['a'] = t['a'] + 1
>__getitem__, key = a
>__setitem__, key = a
>>>> t['a'] += 1
>__getitem__, key = a
>__setitem__, key = a
>>>> t['b'] = []
>__setitem__, key = b
>>>> t['b'] = t['b'] + [1]
>__getitem__, key = b
>__setitem__, key = b
>>>> t['b'] += [2]
>__getitem__, key = b
>__setitem__, key = b
>
>So to me it seems that when we substitute t['a'] or t['b'] for x,
>x is evaluated twice with the augmented version, just like it
>is with the not augmented version.

$ cat x.py

def getindex(ind = 0):
    print 'getindex() called'
    return ind

a = [0, 1, 2, 3, 4, 5]
a[getindex(0)] = a[getindex(0)] + 17
print a
a[getindex(1)] += 22
print a

$ python x.py
getindex() called
getindex() called
[17, 1, 2, 3, 4, 5]
getindex() called
[17, 23, 2, 3, 4, 5]

In this case, getindex() is a rather pointless function, but it could
be an expensive one or one with side effects or even one which alters
state, so that it gives different values on subsequent calls with the
same argument.

The += version finds the object to be operated upon once, the expanded
version does it twice.


-- 
Jim Segrave           (jes at jes-2.demon.nl)




More information about the Python-list mailing list