I am running some Python3 code using the IDLE and I would like to understand why for
a = {'a':1,'b':2}
both:
a.keys()-'a'
(not even sure why this one works) and
a.keys()-{'a'}
produce the same result.
Weirdly enough, the second option seems produce different outputs once the operation is performed inside a function (and call from the IDLE) or directly run from the IDLE...
The thing to understand here is the kind of entities you are subtracting.
a.keys()
is an iterable. Which simply means that it can be iterated through using a for
or iter
. Formally speaking , in python anything is an iterable that implements __iter__
function. Check this link
>> type(a.keys)
>> dict_keys
And dict_keys
is an iterable, how do you know that? because it has an attribute __iter__
.
>> hasattr(a.keys() , '__iter__')
>> True
a.keys()
returns a view
object. Which allows you to subtract other iterables from itself. As stated in the docs:
dictview - other Return the difference between the dictview and the other object (all elements in dictview that aren’t in other) as a new set.
So, to subract something from a.keys()
, that entity should be an iterable too.
In your case :
a.keys() - 'a'
works because strings are iterables in python
>> hasattr('a' , '__iter__')
>> True
So, strings are iterables
a.keys() - {'a'}
works because {'a'}
is a set, which is an iterable
>> hasattr({'a'} , '__iter__')
>> True
On the other hand if you try this:
>> a.keys() - 1
>> TypeError: 'int' object is not iterable
So, you cannot subtract two objects which are not iterables. Hope this helps :)