Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How to initialize a nested list with empty values which i can append to

i'm learning python and hit a wall. I am trying to define a 2d list which i can later use to append values. This corresponding to a grid of width *height

I tried using [] to initialize the empty lists but then the wid is ignored. I tried using None as a placeholder but then i can't append

wid = 3
hgt = 3
l1 = [[]*wid ] * hgt
l = [[None]*wid ] * hgt
l[1][1].append("something")

Result

l1: [[], [], []]

l: [[None, None, None], [None, None, None], [None, None, None]]

Error:

append: AttributeError: 'NoneType' object has no attribute 'append'

desired result: [[[], [], []], [[], [], []], [[], [], []]]

like image 642
Jop Avatar asked Jun 01 '26 19:06

Jop


1 Answers

Try using a list comprehension within a list comprehension:

>>> [ [ [] for i in range(wid) ] for i in range(hgt) ]
[[[], [], []], [[], [], []], [[], [], []]]

Note this is preferred to list multiplication because each of these lists is unique. Compare:

>>> x = [ [[] for i in range(wid)] for i in range(hgt) ]
>>> x[1][1].append('a')
>>> x
[[[], [], []], [[], ['a'], []], [[], [], []]]

vs.

>>> y = [ [[]] * wid for i in range(hgt) ]
>>> y[1][1].append('a')
>>> y
[[[], [], []], [['a'], ['a'], ['a']], [[], [], []]]

vs.

>>> z = [ [[]] * wid ] * hgt
>>> z[1][1].append('a')
>>> z
[[['a'], ['a'], ['a']], [['a'], ['a'], ['a']], [['a'], ['a'], ['a']]]

Where, in the second and third cases, 'a' appears in multiple cells! And using None does not avoid this problem:

>>> m = [ [None] * wid ] * hgt
>>> m
[[None, None, None], [None, None, None], [None, None, None]]
>>> if m[1][1] is None:
...     m[1][1] = ['a']
... else:
...     m[1][1].append('a')
...
>>> m
[[None, ['a'], None], [None, ['a'], None], [None, ['a'], None]]

tl;dr - use the double list comprehension. In my opinion, it's the most readable option anyway.

like image 153
chris Avatar answered Jun 04 '26 08:06

chris