TypeError: unsupported operand type(s) for &: 'dict' and 'dict'

d1 = dict(a=1, b=2, c=3, d=4)
d2 = dict(b=20, d=40, e=50)

for item in d1.keys():
… print(item)

a
b
c
d

for item in d1:
… print(item)

a
b
c
d
same result
so keys() not required for loop to iterate

but if do set operator like & (intersection) with dictionaries, why required keys()

d1&d2
Traceback (most recent call last):
File “”, line 1, in
TypeError: unsupported operand type(s) for &: ‘dict’ and ‘dict’

d1.keys() & d2.keys()
{‘d’, ‘b’}

But

d1|d2
{‘a’: 1, ‘b’: 20, ‘c’: 3, ‘d’: 40, ‘e’: 50}
works

Please help me

as of PEP 584, dictionaries do not allow the intersect operator, precisely because of cases like this actually.
What value should d1&d2['b'] have? It would have to be 20 to be consistent with d1|d2, but I’d find that confusing.

It wouldn’t make much sense since you can’t ‘&’ type str strings which is what you are implying that you want to do from the examples just prior to this ‘&’ boolean operation (you’re printing the dictionary keys in both of the examples by extracting the keys via for loops).

You can of course perform the following (though not sure if this is the outcome that you want):

d1 = dict(a=1, b=2, c=3, d=4)
d2 = dict(b=20, d=40, e=50)

# Obtain keys of both dictionaries, pair them together inside of a list
print(list(zip(d1, d2)))

>>> [('a', 'b'), ('b', 'd'), ('c', 'e')]
1 Like

Your 2 loops:

 for item in d1.keys():

and:

 for item in d1:

are iterating over 2 different types of object.

The d1.keys() loop is iteraing over a dict_keys object, which is a
special proxy to the dictionary, not some list of all the keys:

 >>> d={}
 >>> k=d.keys()
 >>> type(k)
 <class 'dict_keys'>

The d1 loop is iterating over a dict.

A for-loop calls iter() on the thing it is given. It happens that both
a dict and a dict_keys will yield the keys from the dictionary when
something calls iter() on them, and thus the 2 loops iterate over the
keys.

But they are different, and have different properties.

It is meaningful and useful to be able to treat dict_keys objects like
sets and allow & - each is effectively a kind of set-of-keys thing.

You’d think you could do that with dicts, but it’s actually fraught
with complication. Consider these dicts:

 {'a': 1}
 {'a': 2}

First, you might reasonably expect dict & dict to give dict. What
should be in it? {'a':1} or {'a':2}? Or, equally reasonably, {}
because although they have the same keys the values are not the same.

It is better to not support it, and instead only support it on
dict_keys because they are clearly just involving the keys.

1 Like

Thanks for your explanation. it is now clear understanding.