Could you explain this rebinding (or some other action) on "nums = nums"?
Terry Reedy
tjreedy at udel.edu
Tue Dec 1 17:37:34 EST 2015
On 12/1/2015 4:36 PM, Denis McMahon wrote:
> On Tue, 01 Dec 2015 16:18:49 -0500, Terry Reedy wrote:
>
>> On 12/1/2015 3:32 PM, Denis McMahon wrote:
>>> On Tue, 01 Dec 2015 03:32:31 +0000, MRAB wrote:
>>>
>>>> In the case of:
>>>>
>>>> tup[1] += [6, 7]
>>>>
>>>> what it's trying to do is:
>>>>
>>>> tup[1] = tup[1].__iadd__([6, 7])
>>>>
>>>> tup[1] refers to a list, and the __iadd__ method _does_ mutate it, but
>>>> then Python tries to put the result that the method returns into
>>>> tup[1].
>>>> That fails because tup itself is a tuple, which is immutable.
>>>
>>> I think I might have found a bug:
>>
>> What you found is an specific example of what MRAB said in general
>> above.
>>
>>> $ python Python 2.7.3 (default, Jun 22 2015, 19:33:41)
>>> [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license"
>>> for more information.
>>>>>> tup = [1,2,3],[4,5,6]
>>>>>> tup
>>> ([1, 2, 3], [4, 5, 6])
>>>>>> tup[1]
>>> [4, 5, 6]
>>>>>> tup[1] += [7,8,9]
>>> Traceback (most recent call last):
>>> File "<stdin>", line 1, in <module>
>>> TypeError: 'tuple' object does not support item assignment
>>
>> The bug is trying to replace a member of a tuple. The correct code, to
>> avoid the exception while extending the list, is
>>
>> tup[1].extend([7,8,9])
>>
>>>>>> tup[1]
>>> [4, 5, 6, 7, 8, 9]
>
> You snipped the important bit of my original post, which was the state of
> tup after the TypeError occurred.
No I did not. The change to tup[1] right there above, after giving the
correct way to make the change.
> After the error,
>>>> tup[1]
> [4, 5, 6, 7, 8, 9]
This is exactly what I posted.
>>>> tup
> ([1, 2, 3], [4, 5, 6, 7, 8, 9])
This is a repeat of the same thing and adds no new info.
> The "bug" I refer to is that despite giving the TypeError, the tuple
> allowed the assignment of the mutated list to replace the original list.
No it did not. As MRAB noted, the list is mutated and the attempted
assignment causes an exeption. This has been discussed before more than
once ever since augmented *assignment* was introduced.
>>> tup = ([],[])
>>> id(tup[1])
711662188872
>>> tup[1] += [1]
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
tup[1] += [1]
TypeError: 'tuple' object does not support item assignment
>>> tup[1]
[1]
>>> id(tup[1])
711662188872
>>> tup[1] = tup[1].extend([2])
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
tup[1] = tup[1].extend([2])
TypeError: 'tuple' object does not support item assignment
>>> tup[1]
[1, 2]
>>> id(tup[1])
711662188872
Reading the augmented assignment doc carefully should make it clear that
"tup[1] += [1]" is the same as "tup[1] = tup[1].extend([2])" except that
evaluation of "tup[1]" happens just once instead of twice.
--
Terry Jan Reedy
More information about the Python-list
mailing list