1

I want to create a n x n 2D list of lists in python, where all elements are equal to False. So I tried this:

array = [[False] * n] * n

This appears to give me what I want, but if I want to change an element in the (i, j) position, say:

array[i][j] = not array[i][j]

this changes all the elements in the jth column, rather than just affecting (i, j) position. I realize this is because all the rows in the list are just referencing the first row.

Is there a non verbose way in vanilla python (no numpy) to create a 2D list of lists without the internal referencing (is that what it's called) ?

kchak
  • 7,570
  • 4
  • 20
  • 31

1 Answers1

1

You can use a list comprehension.

array = [[False for _ in range(n)] for _ in range(n)]

See here:

>>> from pprint import pprint
>>> n = 10
>>> array = [[False for _ in range(n)] for _ in range(n)]
>>> pprint(array)
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]

Now if you want to change an element at (i, j), you can just assign to it:

>>> array[2][4] = True
>>> pprint(array)

[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, True, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
[False, False, False, False, False, False, False, False, False, False]
erip
  • 16,374
  • 11
  • 66
  • 121
  • 1
    It would be more pythonic to use anonymous variables instead of x, thus `array = [[False for _ in range(n)] for _ in range(n)]` as you do not use `x` in the expressions. – lejlot Dec 13 '15 at 14:38
  • 1
    also if you try to iterate oves **values** of array (which you do) you could just use `for row in array: print row` instead of any indexing (cleaner and simplier); or even more pythonic - import pprint from pprint and pprint the whole array: `from pprint import pprint; pprint(array)` – lejlot Dec 13 '15 at 14:40
  • Never heard of `pprint`. Thanks @lejlot! – erip Dec 13 '15 at 14:44
  • Anonymous variables seem nice. Not to mention `pprint` and List comprehension! Thanks for the tips. – kchak Dec 14 '15 at 07:00