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?
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).