Adding a dictionary to a list using the __iadd__
notation seems to add the keys of the dictionary as elements in the list. Why? For example
a = []
b = {'hello': 'world'}
a += b
print(a) # -> ['hello']
The documentation for plus-equals on collections doesn't imply to me that this should happen:
For instance, to execute the statement
x += y
, where x is an instance of a class that has an__iadd__
() method,x.__iadd__(y)
is called. If x is an instance of a class that does not define a__iadd__()
method,x.__add__(y)
andy.__radd__(x)
are considered, as with the evaluation ofx + y
But, logically, both a + b
and b + a
raise a TypeError. Furthermore, b += a
raises a TypeError too. I don't see any special implementation in the source that would explain things, but I'm not 100% sure where to look.
The closest question on SO I found is this one, asking about += on dictionaries, but that's just asking about a data structure with itself. This one had a promising title about list self-addition, but it claims "__add__
" is being applied under the hood, which shouldn't be defined between lists and dictionaries.
My best guess is that the __iadd__
is invoking extend
, which is defined here, and then it tries to iterate over the dictionary, which in turn yields its keys. But this seems... weird? And I don't see any intuition of that coming from the docs.
for key in b
then dictionary gives you alsokeys
, notvalues
. Andlist(b)
also gives youkeys
, notvalues
. So maybe it works likea += list(b)
– Pagelist(b)
but someone decide thatb
will return only keys when you use it withfor
-loop,list()
and the same in+=
. Someone decided that keys can be more useful thenvalues
– Pagea + b
then? Iterator behaviour is documented but this doesn't seem to be. – Grimaud+
and+=
may not use the same code - and maybe they don't have time to write it in the same way. – Page