def make_set(rad):
y = []
for i in range(0, rad):
x = []
for j in range(0, rad):
x.append(0)
y.append(x)
return y
def make_set_basic(rad):
z = [[0] * rad] * rad
return z
What is problematic about the latter implementation (make_set_basic)?
When making lists using the multiplication operator, you have to take into account if the object being created is mutable or inmutable.
In python integers are inmutables, after an arithmetic operation, a new object is created:
In the example above, the list has three elements all of them pointing to the same object (this is checked using the
idbuiltin). However, when the first element is modified, this element now points to another different object and the change doesn’t affect the other elements in the list.On the other hand, if objects are mutable, when you use a method that modifies the object in place, the result that you get is as if the modification were applied to all objects in the list:
Note that in this example, after callin the
appendmethod, no new object has been created as in the previous example. Given that all the elements in the list still point to the same object (theidbuiltin returns the same value for all of them), the new state of the object is displayed for all the elements in the list.Hence, answering your question, since you probably don’t want this behaviour, you need to create the list that you need in a nested loop to make sure that all elements in the list point to a different object that you can modify without changing the state of other elements in the list as a side effect.