I have face this weird behavior I can not find explications about.
MWE:
l = [1]
l += {'a': 2}
l
[1, 'a']
l + {'B': 3}
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: can only concatenate list (not "dict") to list
Basically, when I +=
python does not raise an error and append the key to the list while when I only compute the +
I get the expected TypeError
.
Note: this is Python 3.6.10
Assignment operators in Python are in-fix which are used to perform operations on variables or operands and assign values to the operand on the left side of the operator. It performs arithmetic, logical, and bitwise computations.
l += ...
is actually calling object.__iadd__(self, other)
and modifies the object in-place
when l
is mutable
The reason (as @DeepSpace explains in his comment) is that when you do l += {'a': 2}
the operation updates l
in place only and only if l
is mutable. On the other hand, the operation l + {'a': 2}
is not done in place resulting into list + dictionary -> TypeError
.
(see here)
l = [1]
l = l.__iadd__({'a': 2})
l
#[1, 'a']
is not the same as +
that calls object.__add__(self, other)
l + {'B': 3}
TypeError: can only concatenate list (not "dict") to list
So as the authors say this is not a bug. When you Do a += b
it is like b
come to a
's house and changing it the way that a
like it to be. what the Authors say is when you do a + b
it cannot be decided which one's style will get prioritized. and no one knows where will the result of a + b
will go until you execute it. So you can't decide whose style it would be. if it is a
style it would be [1, 'a']
's, and if it is b
style it would be an error. and therefore it cannot be decided who will get the priority. So I don't personally agree with that statement. because when you take the call stack a
is in a higher place than b
. when there is a expression like a + b
you first call a.__add__(self, other)
if a.__add__
is NotImplemented
(in this case it is implemented). then you call a.__radd__(self, other)
. which means call other.__add__
in this case b.__add__
. I am telling this based on the place of the call stack and the python community may have more important reasons to do this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With