Tuples and immutability

Antoon Pardon antoon.pardon at rece.vub.ac.be
Wed Mar 12 05:39:35 EDT 2014


Op 12-03-14 07:28, Steven D'Aprano schreef:
> On Tue, 11 Mar 2014 23:25:19 -0400, Terry Reedy wrote:
>
>> Nope, 'similar' is not 'equivalent'. Evaluating x twice instead of once
>> and possibly allocating a new object versus not take extra time. In a
>> statement like "x.y.z[3*n+m] += 1", calculating the target dominates the
>> time to increment, so this form should be nearly twice as fast.
> Excellent point Terry!
>
> I always forget that the target of an augmented assignment may not be a 
> simple name like "x" but can be an arbitrary complex reference, anything 
> that is a legal assignment target. Because += is documented as only 
> evaluating the expression once it can behave quite differently to the 
> `spam = spam + 1` case. Evaluating the right hand side may have side-
> effects that change what the left hand side evaluates to. This is not the 
> case with the augmented assignment.

The documentation is wrong at that point as the following code illustrates.

| import sys
| write = sys.stdout.write
|
| class logdict:
|     def __init__(self):
|         self.lst = {}
|
|     def __setitem__(self, key, value):
|         write('[%s] <= %s\n' % (key, value))
|         self.lst[key] = value
|
|     def __getitem__(self, key):
|         value = self.lst[key]
|         write('[%s] => %s\n' % (key, value))
|         return value
|
| tab = logdict()
| tab['key'] = 'value'
| tab['key'] += ' with extra tail'
| write('====\n')
| tab = logdict()
| tab['key'] = 'value'
| tab['key'] = tab['key'] + ' with extra tail'

If you run this code, you get the following result:

| [key] <= value
| [key] => value
| [key] <= value with extra tail
| ====
| [key] <= value
| [key] => value
| [key] <= value with extra tail

As you can see there is no difference here in the evaluations done
between using

| tab['key'] += ' with extra tail'

or

| tab['key'] = tab['key'] + ' with extra tail'



More information about the Python-list mailing list