a = [[0]*3] * 4
print(a[0] is a[1]) # True
when I initialize a two dimensional array that way, things went wrong. Took me a bit time to find this unexpected behavior. So is this syntax only work on immutable object?
a = [[0]*3] * 4
print(a[0] is a[1]) # True
when I initialize a two dimensional array that way, things went wrong. Took me a bit time to find this unexpected behavior. So is this syntax only work on immutable object?
It "worked" in your example too, in its way. This is just how the implementation of list.__mul__
interprets what you want. The list can't construct new objects, it doesn't know how to create new objects from whatever objects it happens to contain. It expands itself with new references to those objects.
You get the same behavior with immutable integers
>>> x = [0] * 3
>>> x[0] is x[1]
True
You can get the two dimensional array with
>>> a = [[0]*3 for _ in range(4)]
>>> a[0] is a[1]
False
The reason why [0] * 3
does what you want is that it is creating list that contains 3 references to the same immutable 0
.
What went"wrong"
?
It does make a two-dimensional list. (I don't know if that's a thing but I mean to say it makes the list in a form where you can convert it to a 2-D array).
To convert it to a proper array, you will have to use
import numpy as np
a = [[0]*3] * 4
a = np.array(a)
You can make this immutable by converting it to a tuple.