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]*heightyou end up with the same list object in each row. Therowarray 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!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)]thenrowexprwill 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:
Each time
[None] * widthis evaluated it generates a new list.