Consider this code:
a = {...} # a is an dict with arbitrary contents
b = a.copy()
How do I check if a type is mutable in Python?
Keys must be hashable - that's all that's forced upon you. In particular, you can have a user-defined class whose instances are hashable but also mutable - but this is generally a bad idea.
By not sharing values between the two dicts. It's generally OK to share the keys, because they should be immutable (and will be, for built-in types). Copying the dictionary, in the sense of the copy
standard library module, is definitely safe. Calling the dict constructor here works, too: b = dict(a)
. You could also use immutable values.
All built-in immutable types are hashable. All built-in mutable types are not hashable. The constraint on dict keys simply requires that the built-in hash
function works on the key, which in turn requires that its class implements the __hash__
magic method.
However, the code may break subtly or unexpectedly if an object's hash could ever change during its lifetime. For a pathological example:
>>> import random
>>> class x:
... def __hash__(self): return random.randint(0, 100)
...
>>> a, b = x(), x()
>>> c = {a:1, b:2}
>>> c[a]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: <__main__.x object at ...>
This is why trying to make a mutable, hashable type is ill-advised: the hash is expected not to change, but is also expected to reflect the state of the object.
No.
A type is mutable if it is not immutable. A type is immutable if it is a built-in immutable type: str
, int
, long
, bool
, float
, tuple
, and probably a couple others I'm forgetting. User-defined types are always mutable.
An object is mutable if it is not immutable. An object is immutable if it consists, recursively, of only immutable-typed sub-objects. Thus, a tuple of lists is mutable; you cannot replace the elements of the tuple, but you can modify them through the list interface, changing the overall data.