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