Reputation: 1131
I have a doubt when i create a multidimentional array with None
element, i.e.
all elements are having same id but only elements of a single row are changed.
def array(a, b):
none = [None for _ in range(b)]
return [none for _ in range (a)]
So now arr = array(4, 5)
gives
[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
Now when I do arr[0][4] = 45
It gives
[[None, None, None, None, 45],
[None, None, None, None, 45],
[None,None, None, None, 45], [None, None, None, None, 45]]
Every 4th index value is changed to 45 So I tried
def id_array(a, b):
none = [id(None) for _ in range(b)]
return [none for _ in range (a)]
Now id_arr = id_array(4, 5)
[[138022184, 138022184, 138022184, 138022184, 138022184], [138022184, 138022184, 138022184, 138022184, 138022184], [138022184, 138022184, 138022184, 138022184, 138022184], [138022184, 138022184, 138022184, 138022184, 138022184]]
i.e. every value has same id
so while doing arr[0][4] = 45
shouldn't every value of arr change to 45 because everyone has same id
and why only 4th index of every row being changed.
Upvotes: 1
Views: 60
Reputation: 4771
In your example you are creating a list of identical lists, i.e references to exact same list. If you check the Ids
>>> def array(a, b):
none = [None for _ in range(b)]
return [none for _ in range (a)]
>>> bs = array(4,5)
>>> [id(b) for b in bs]
[139931681000480, 139931681000480, 139931681000480, 139931681000480]
If you arr[0][4] = 45
you simply changing what the fourth list element points to and not the None
element self. It becomes more clear if you add a list with distinct id
>>> bs.append([1,2,3,4])
>>> bs[0][1] = 1
>>> bs
[[None, 1, None, None, None],
[None, 1, None, None, None],
[None, 1, None, None, None],
[None, 1, None, None, None],
[1, 2, 3, 4]]
Upvotes: 0
Reputation: 16779
You're reusing the same none
list for every element you append to your return value, when you want each one to be distinct. That's why updates to none
via one index are reflected across all others — because you are editing only a single list, even though you may have multiple references to it.
The way to remedy this behavior is to simply place the first comprehension inside the second:
def array(a, b):
return [[None for _ in range(b)] for _ in range (a)]
Upvotes: 3