In Python 3.7, I'd like to calculate the intersection of two dictionaries' keys. To do this, I'd like to call the .intersection()
method on their keys()
, however it does not work.
.keys() produces a set-like object, however most set methods don't work on it. What works however is the extremely unknown bitwise operator overloads for set-like objects, like &
.
m = {'a':1, 'b':2}
n = {'b':3, 'c':4}
m.keys().intersection(n.keys()) # Pythonic, but doesn't work
m.keys() & n.keys() # works but not readable
set(m.keys()).intersection(set(n.keys())) # works, readable, but too verbose
I find that the &
overload on a set-like object is extremely rarely used and is not known by most programmers. Method names like .intersection()
or .union()
is self-documenting and definitely more Pythonic by this definition.
Why isn't it supported then? Even the documentation lists the &
and .intersection()
methods like aliases, not mentioning that only &
is supported on set-like objects.
note: For some reason, in IPython the autocomplete lists .isdisjoin()
as a method which is available on dict.keys()
. Out of the 17 set methods, 1 is present.
dict
views only guarantee the API ofcollections.abc.Set
, not to be equivalent toset
itself:So they're not claiming to match
set
, or evenfrozenset
, justcollections.abc.Set
collections.abc.Set
doesn't require any of the named methods aside fromisdisjoint
(which has no operator equivalent).As for why
collections.abc.Set
doesn't require the named methods, it may be because they are somewhat more complex (most take varargs, and the varargs can be any iterable, not just other set-like things, so you can, for example,intersection
with many iterables at once), and they may have wanted to limit the complexity required to implement new subclasses (especially virtual subclasses, that wouldn't inherit any of the methodscollections.abc.Set
might choose to provide).All that said, I generally agree with your point that it seems needlessly inconsistent to omit the method forms. I'd recommend you open a bug on the Python bug tracker requesting the change; just because it only guarantees
Set
compatibility doesn't mean it can't do more.The format should be
where other is any iterable. m.keys() is dict_keys not a set so that won't work.
will work :)