Okay, the following answer will get very wordy but hopefully lucid enough... If any clarification is required please let me know.
In the first statement a is b, you are basically comparing the address of the two objects (or pointers/references to the same object). So you are asking if a is the same as b, and you get True.
But in the second statement id(a) is id(b) you aren't comparing the addresses of a and b. You are comparing the address of the two objects that are holding the value of the addresses of a and b.
Still confused? Let's see an example..
a = [1]
b = a
a is b      #True
The reason for the above output: a and b are pointing to the same list object
address1 = id(a)
address2 = id(b)
address1 is address2      #False
The reason for the above output: address1 and address2 are integers and while they contain the same value, those values are stored in different objects. Similarly when you run id(a) is id(b), you are comparing the two different address-value-holding objects and not the object addresses.
SOLUTION:
Just type,
id(a) == id(b) # This will tell you whether the location of a and b is the same. 
#If the output is true, then a and b point to the same object.
Hope that makes things clearer!