+ 1

Python bug or feature? : list as a tuple item gets reassigned, raising error but still successful!

I try to re-assign a tuple item which is a list, by adding one more element to the list. Of course an error shows up because tuple item can’t get re-assigned. But it’s interesting that, although I got an exception (an error), the item actually get re-assigned! Can someone explain what happened? P/S: just run my attached code first. My idea expressed out well there! https://code.sololearn.com/c1obOiFrUk9c/?ref=app

24th Oct 2018, 7:55 AM
Pela Lala
Pela Lala - avatar
5 odpowiedzi
+ 1
Well, you have to know that when using += operator, you effectively calling __iadd__ method of first operand with second operand like params, and assigning result to first operand. In your case: animal_tuple[2]= animal_tuple[2].__iadd__(['panther']) Then python execute FIRST the __iadd__ method (and its perfectly possible) which append ['panter'] and return itself (the modified list), then, AFTER, it try to assign to animal_tuple[2] to it and THIS cause an error becuase assignement its no allowed on tuple BUT AT THIS POINT THE ITEM LIST IS YET MODIFIED
24th Oct 2018, 10:34 AM
KrOW
KrOW - avatar
+ 6
tuple1 += tuple2 doesn't append tuple2 to tuple1, but redefines tuple1 as tuple1 + tuple2. That's perfectly possible. .append, .pop etc. are list operations and don't change the tuple. The tuple still consists of the same items as before (two strings and a list), you're just modifying the list "internally". By using animal_tuple[2] = temp you're trying to change what the tuple holds at index 2. That's a change of the tuple itself and isn't allowed. The problem with animal_tuple[2] += ['panther'] is probably that list += element works for lists, but python doesn't know animal_tuple[2] += ['panther'] is an operation that aims on the list element and not on the tuple as such. tuple[index] += element raises a TypeError because you can't change the value of a tuple. However in this specific case, tuple[index] += element is possible because tuple[index] is a list. So it's an error (in general) that works in this specific case. /Edit: By the way, I'm just trying to find an explanation for what's happening. I'm not saying that the behavior is not a bug. Actually I think that the fact that a statement can be executed as planned AND raises an exception at the same time is at least a bit... surprising :D
24th Oct 2018, 9:03 AM
Anna
Anna - avatar
+ 1
Dear Anna , you’re trying to help me again. Lovely! So you enjoyed the magic just the way I did. By the way, I think that KroW has the answer for us. That is what I (and maybe you Anna too) felt-thought of the way Python behaves in this case, but couldn’t explain clearly and technically. Dear KrOW , your answer is very excellent. Thank you so much!!! I didn’t expect a method like __iadd__() is the ‘real existence’ of the ‘+=‘ operator. I will do more research in the depth of Python to know what it really does.
24th Oct 2018, 11:56 AM
Pela Lala
Pela Lala - avatar
+ 1
Pela Lala I simplified all because its not mandatory call to __iadd__ but this happen on lists... Anyway, you are welcome 👍👍👍
24th Oct 2018, 2:20 PM
KrOW
KrOW - avatar
0
To Anna and KrOW , I’ve just known that we has accidentally been discussing a recorded case in Python Documentation 3.7.1 Just make a search for the text: “Why does a_tuple[i] += [‘item’] raise an exception when the addition works?” I feel glad for an unknown reason.
3rd Nov 2018, 9:44 AM
Pela Lala
Pela Lala - avatar