Search code examples
pythondictionarysetset-difference

Difference operations in dictionary keys in python


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


Solution

  • 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 :

    1. a.keys() - 'a' works because strings are iterables in python

      >> hasattr('a' , '__iter__')

      >> True

      So, strings are iterables

    2. 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 :)