So I'm trying to generate a nested list in Python based on a width and a height. This is what I have so far:
width = 4
height = 5
row = [None]*width
map = [row]*height
Now, this obviously isn't quite right. When printed it looks fine:
[[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None]]
But attempting to assign a value to a position like so:
map[2][3] = 'foo'
I get:
[[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo']]
Clearly this happens because each sublist is really just referencing the same object, row, so changing one, changes them all. So this is closest I've got!
How can I dynamically generate a nested list? Thanks!
When you do [row]*height
you end up with the same list object in each row. The row
array reference is repeated in each row which means each row is actually pointing to the same list object. Hence modifying one row actually modifies all rows.
Take a look at what happens when you print the id()
for each row. They're all the same!
>>> grid = [[None] * width] * height
>>> [id(row) for row in grid]
[148014860, 148014860, 148014860, 148014860, 148014860]
You can get python to generate separate-but-identical lists for each row by using a list comprehension. When you use [rowexpr for i in xrange(height)]
then rowexpr
will be evaluated once per row. The trick then is to use an expression that will result in a unique list each time it is evaluated.
This'll make more sense if you see it in action:
>>> grid = [[None] * width for i in xrange(height)]
>>> grid[2][3] = 'foo'
>>> grid
[[None, None, None, None],
[None, None, None, None],
[None, None, None, 'foo'],
[None, None, None, None],
[None, None, None, None]]
Each time [None] * width
is evaluated it generates a new list.
>>> [id(row) for row in grid]
[148016172, 148015212, 148016236, 148016108, 148016332]
I use something like this:
w = 5
h = 5
map = []
for i in range(h):
row = []
for j in range(w):
row.append(None)
map.append(row)
print map
map[2][3] = 'foo'
print map
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With