-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
Currently, the use of the (*) operator on a list is to duplicate a list by creating multiple references to the same object. While this works intuitively for immutable objects (like [True] * 5) as these immutable references are replaced when the list is assigned to, it makes the operator nigh unusable for mutable objects.
The most obvious case is when the operator is duplicated in a sequence like this:
arr = [[True] * 5] * 5
This does not create a matrix-like arrangement of the immutable truth variable, but instead creates a list of 5 references to the same list, such that a following assignment like arr = False will not change just that one index, but every 4th element of each list in the outer list.
This also makes the sequence construction using a mutable type a problem. For example, assume a class Foo:
class Foo: def __init__(self): self.val = True
def set(self): self.val = False
def __repr__(self): return str(self.val)
If I then use sequence repetition to create a list of these like so:
arr = [Foo()] * 5
This will create a list of references to the same Foo instance, making the list construction itself effectively meaningless. Running the set() method on any of the instances in the list is the same as running it on all the instances in the list.
It is my opinion that the sequence repetition operator should be modified to make copies of the objects it is repeating, rather than copying references alone. I believe this would both be more intuitive from a semantic point of view and more useful for the developer.
This would change the operator in a way that is mostly unseen in current usage ( * 3 would still result in [5, 5, 5]) while treating mutable nesting in a way that is more understandable from the apparent intent of the syntax construction.
Reference regarding previous discussion: https://bugs.python.org/issue27135