TFF
TFF

Reputation: 33

The `or` operator on dict.keys()

As I've been unable to find any documentation on this, so I'll ask here.

As shown in the code below, I found that the or operator (|), worked as such:

a = {"a": 1,"b": 2, 2: 3}
b = {"d": 10, "e": 11, 11: 12}

keys = a.keys() | b.keys()
aonce = a.keys() | a.values()
bonce = b.keys() | b.values()

for i in keys:
    print(i, end=" ")
print()
for i in aonce:
    print(i, end=" ")
print()
for i in bonce:
    print(i, end=" ")
print()

Which produces the result, in some order:

2 d 11 a b e   
3 1 2 a b   
10 e 11 12 d   

Initially I assumed these iterable was compatible with |, similar to the way sets are, however. Testing with other iterable, such as a list.__iter__(), threw an error. Even;

values = a.values() | b.values()
for i in values:
    print(i, end=" ") 
print()

Which I'd assume worked, due to the use of dict.values() in the previous examples, threw an error.

So, my question is; What on earth have I come across, and more importantly, how reliable is it? What subclass does my arguments need to be, for me to be able to use this?

Upvotes: 3

Views: 411

Answers (1)

donkopotamus
donkopotamus

Reputation: 23186

The Python 3 Documentation notes that the dict.keys method is set-like and implements collections.abc.Set.

Note that dict.values is not set-like even though it might appear to be so in your examples:

aonce = a.keys() | a.values()
bonce = b.keys() | b.values()

However these are leveraging off the fact that the keys view implements __or__ (and __ror__) over arbitrary iterables.

For example, the following will not work:

>>> a.values() | b.values()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'dict_values' and 'dict_values'

Upvotes: 5

Related Questions