I would like to do a brief comparison on membership tests on set vs list
Membership tests invoke __contains__ dunder(if class implement this method). So, if we write 
>>> 1 in [1,2] 
it will equivalent to 
>>> list.__contains__([1,2],1)
>>> True
If we do:
>>> [1,2] in [1,2,3]
>>> False #We get False instead of TypeError here
But why is above case not applicable to sets? Membership tests work in a different way in list and set. Infact list and set are implemented differently. Talking about set, they are implemented using Hash-Table. This allow sets to perform membership test i.e. lookups in O(1) as compared to list where lookups are O(n). So when in is performed on a set, __contains__ try to compute the hash of the object that need to be looked using __hash__. Since 
lists are unhashable in python, you get the error: TypeError: unhashable type: 'list'. If you do same with list you won't get any error since list don't compute hash for membership testing.
In short membership tests cannot be performed on sets with an object that is unhashable. Generally speaking all mutable objects(list, sets, dict) are unhashable.