0

This is not really a question about an error. Rather, a clarification on how things work.

I am putting an element(0 for example) inside an array which is also inside an array. Doing it iteratively, the code looks like this:

arr = [[0 for x in range(2)] for x in range(2)]

Recursively,

def zero(array,n,i):
if i >= n:
    return array
else:
    array[i].append(0)
    return zero(array,n,i+1)

arr = [[]] * 2
print zero(arr,2,0)

They would both have an output like this: [[0,0],[0,0]]

I did not get the process that the recursion underwent(I just accidentally made that code through trial and error.).

What I did not get was since I am appending zero in the first array(with index zero) inside the bigger array, shouldn't '0' be appended only in the first array and not on the second array? But that is not the case, '0' was appended to both array. And when it returns the function, instead of appending '0' to the second array, it was appended to both array again.

I tried to trace it but I really don't understand how it happened. Thank you for the response.

levi
  • 3
  • 2
  • 3

2 Answers2

2

This would be because

arr = [[]] * 2

is creating another reference to the same list construct. So you have an array with two elements both of which are a reference to the same list. Thus an application on one of them, such as appending an element, will cause that same operation to be reciprocated to the other.

Cocksure
  • 270
  • 1
  • 10
1

Breaking down the constituent parts of the list comprehension using the interactive interpreter:

>>> arr = [[0 for x in range(2)] for x in range(2)]
>>> print arr
[[0, 0], [0, 0]]
>>> inner_array = [0 for x in range(2)]
>>> print inner_array
[0, 0]
>>> total_arr = [inner_array for x in range(2)]
>>> print total_arr
[[0, 0], [0, 0]]

So you have an array of [0,0], and then place that in the outer list comprehension which creates that same array twice, due to the range(2) component.

One can verify that they are the exact same array as follows:

>>> id(inner_array)
139834121190864
>>> id(total_arr[0])
139834121190864
>>> id(total_arr[1])
139834121190864

id returns the address of the object, and here, they are all the same.

khampson
  • 14,700
  • 4
  • 41
  • 43