I think the other replies have answered your question well enough, but your definitions for = are a litle off. The cases 1 and 2 are really the same thing. In Python the names are references to objects. Assignment in Python is like using pointers in C. You are doing mutation, what you mutate is the value of a pointer (and probably some other oddsand ends for garbage collection).
I was going to say the same thing - that cases 1 and 2 are really the same thing - when I realized that's not quite accurate. In his terms, mutation is a special case of re-assignment. That is, re-assignment allows re-binding a name to an entirely different value which may have a different type. Mutation is then re-assignment where the types happen to be the same.