pythonsetoperatorshashabledictview

Why do set operators work with dict_key view objects but not the equivalent set methods?


Edit: Possible duplicate. Only after posting this question and looking in "related questions" was I able to find Why are set methods like .intersection() not supported on set-like objects?, this question may similar enough to be a duplicate.

I am trying to see if the keys from a dictionary are a subset of a set and came upon some confusing behavior of the dict_keys view object and set methods/operators.

Difference between a set and a view points out that:

Only the dict.keys() dictionary view is always a set (insofar that it behaves like a set, but one with a live view of the dictionary)

And the https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects documentation points out that

Keys views are set-like since their entries are unique and hashable. ... For set-like views, all of the operations defined for the abstract base class collections.abc.Set are available (for example, ==, <, or ^).

and the https://docs.python.org/2/library/stdtypes.html#set set type documentation implies the operators (<=, |, ect.) are equivalent to the methods .issubset(), union() ect.

Yet the following code does not reflect these assertions:

> dic = {'first': 'a', 'second': 'b'}

> s = {'first', 'second', 'third'}

> dic.keys() <= s

True

> dic.keys().issubset(s)


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-354-fbf8f9744a80> in <module>
----> 1 dic.keys().issubset(s)

AttributeError: 'dict_keys' object has no attribute 'issubset'

s.issuperset(dic.keys()) does return True however.

Why is disperate behavior present when all indication are that the .issubset() method would work?


Solution

  • As an answer to Why are set methods like .intersection() not supported on set-like objects? points out,

    dict views only guarantee the API of collections.abc.Set, not to be equivalent to set itself (...) these set-like objects are not claimed to match set, or even frozenset, just collections.abc.Set (and) collections.abc.Set doesn't require any of the named methods aside from isdisjoint (which has no operator equivalent).