Cupitor - 1 year ago 75
Python Question

# Filling in a completely empty list of lists in an arbitrary order

I am trying to fill an

`NxN`
list of lists in python. In a way that if seen as a 2D array, first the main diagonal is filled and then other operations are done with other elements (not relevant here). So for example if we have
`dyn_arr=[[[], [], []], [[], [], []], [[], [], []]]`
in the beginning, it should first turn into:
`[[[1], [], []], [[], [1], []], [[], [], [1]]]`
. I assumed this code might do it:

``````dyn_arr = [[[]]* N] * N
idx_set = []
for pointer in range(N):
pointer_pair = [0, pointer]
while pointer_pair[0] < N and pointer_pair[1] < N:
if pointer_pair[0] == pointer_pair[1]:
dyn_arr[pointer_pair[0]][pointer_pair[1]]=[1]
pointer_pair[0] += 1
pointer_pair[1] += 1
``````

But it outputs
`[[[1], [1], [1]], [[1], [1], [1]], [[1], [1], [1]]]`
. Can somebody please explain me what is going on and how I should correct it?

Be careful when creating lists using the multiplication operator. This way will multiply the references to the objects in the list; it will not create copies! So, if you create a list of lists using `a = [[]] * 3`, this will create a list of three elements which are all the same empty array. Changing it (using `.append()`) will change this one same list which is referenced in all three elements of the outer list:

``````a = [[]] * 3
print a  # prints "[[], [], []]"
a[0].append(4)
print a  # prints "[[4], [4], [4]]"
print a[0] is a[1]  # prints "True"
``````

You should always create lists of lists using a list comprehension:

``````# instead of dyn_arr = [[[]]* N] * N use:
dyn_arr = [ [ [] for _i in range(N) ] for _j in range(N) ]
``````

The result will look the same right after creation, but this version creates new arrays for each entry instead of additional references.

This should solve your issues resulting from the original error.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download