Dictionary views "are set-like objects" and can thus be used to compare dictionary contents with other objects. Specifically,
The set-like nature of key-views allows bitwise comparisons. In Python 3, we can find the intersection using the &
operator.
hex_ids = {'#b0a7aa': '9976', '#595f5b': '19367', '#9a8f6a': '24095'}
hex_ids.keys()
# dict_keys(['#595f5b', '#9a8f6a', '#b0a7aa'])
{'#c7ccc0', '#9a8f6a', '#8a8e3e'} & hex_ids.keys()
# {'#9a8f6a'}
Oddly, comparing a list
and key-view is also possible:
['#c7ccc0', '#9a8f6a', '#8a8e3e'] & hex_ids.keys()
# {'#9a8f6a'}
whereas list
and set
objects normally cannot be compared this way.
['#c7ccc0', '#9a8f6a', '#8a8e3e'] & set(['#595f5b', '#9a8f6a', '#b0a7aa'])
# TypeError: unsupported operand type(s) for &: 'list' and 'set'
['#c7ccc0', '#9a8f6a', '#8a8e3e'] & {['#595f5b', '#9a8f6a', '#b0a7aa']}
# TypeError: unhashable type: 'list'
Aside from being set-like, why can key-views be compared to lists using bitwise operators?
Tested on: |Python 3.5.2|Python 3.4.4|Python 2.7.12 (using viewkeys()
)|IPython 5.0.0|
It uses the __rand__
method (short for "reflected and") on the dict_keys
type. Note that the reflected functions are only called if the left operand does not support the corresponding operation and the operands are of different types, which is the case here.
>>> {}.keys().__rand__
<method-wrapper '__rand__' of dict_keys object at 0x109948f18>
For example:
>>> {0:0, 1:1}.keys().__rand__([1, 2])
{1}
For some reason this method was not implemented for sets, which is why that doesn't work:
>>> {0, 1}.__rand__([1, 2])
NotImplemented
I don't know the reason for this omission on sets, but I suspect it's probably "nobody has bothered to write it" because you can use set.intersection
explicitly instead.