Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When can dict_values views be set-like (and why)?

The docs say that values views are not treated as set-like, but sometimes they are:

>>> d = {1: 1}
>>> d.values() | d.keys() 
{1}
>>> d.values() & d.keys() 
{1}
>>> d.values() - d.keys() 
set()

Why implement set-returning set semantics but then fail with an actual set?

>>> d.values() - {1}
TypeError: unsupported operand type(s) for -: 'dict_values' and 'set'
like image 901
wim Avatar asked May 01 '19 17:05

wim


1 Answers

This is actually not dict_values handling the operation(s). The keys_view will strong-arm the operation from the right hand side, by supporting the reflected method(s):

>>> set().__rsub__({}.values())
NotImplemented
>>> {}.keys().__rsub__({}.values())
set()

For similar reasons, set operations will sometimes work or not work with other dict views:

# works, because type(d.items()) implements __rsub__
>>> d.values() - d.items()  
{1}

# fails, because type(d.values()) does not implement __rsub__
>>> d.values() - d.values()
TypeError: unsupported operand type(s) for -: 'dict_values' and 'dict_values'

So, although this behaviour seems to violate duck-typing, the docs remain correct.

like image 106
wim Avatar answered Nov 11 '22 22:11

wim