Some readers on r/python didn’t get the corner case I point out so I wrote the following:
Given:
k1, v1 = int(1), "x"
k2, v2 = float(k1), v1 * 3
In Python 3.9 what does this evaluate to
{k1: v1} | {k2: v2}
- Is the key of the result k1 or k2?
- Is the value of the result v1 or v2?
Specifically, hash(1)
(int) and hash(1.0)
(float) are the same (don’t have to be equal)
You can simplify the example:
>>> {1: "x"} | {1.0: "xxx"}
{1: 'xxx'}
Nice simplification. …That still shows that the first of the equal-by-hash keys and/but the last of the values is used. I thought this first/last thing was noteworthy in this corner case.
You can also ask “what would dict.update()
do?”
>>> d1 = {int(1): "a"}
>>> d2 = {float(1): "aaa"}
>>> d1.update(d2)
>>> d1
{1: 'aaa'}
The merge operator |
and in-place update operator |=
emulate the update
method.
>>> d1 = {int(1): "a"}
>>> d1 | d2
{1: 'aaa'}
Hopefully what you’ve found agrees with traditional dict.update()
behavior.
It can be even simpler:
>>> {1: 'foo', 1.0: 'bar'}
{1: 'bar'}
The explanation is, that 1
and 1.0
are “the same value”, i.e. they have the same hash value and compare equal.
This means that 1.0: 'bar'
updates the existing entry, but because “it is the same key”, the key doesn’t get updated, only the value does.