views:

39

answers:

1

I expected to get a grid of unique random numbers. Instead each row is the same sequence of numbers. What's going on here?

from pprint import pprint
from random import random

nrows, ncols = 5, 5
grid = [[0] * ncols] * nrows
for r in range(nrows):
    for c in range(ncols):
        grid[r][c] = int(random() * 100)
pprint(grid)

Example output:

[[64, 82, 90, 69, 36],
 [64, 82, 90, 69, 36],
 [64, 82, 90, 69, 36],
 [64, 82, 90, 69, 36],
 [64, 82, 90, 69, 36]]
+2  A: 

I think that this is because python uses a weak copy of the list when you call

grid = [...] * nrows

I tried hard coding the list and it worked correctly:

>>> grid = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]
>>> for r in range(nrows):
...     for c in range(ncols):
...             grid[r][c] = int(random() * 100)
... 
>>> pprint(grid)
[[67, 40, 41, 50, 92],
 [26, 42, 64, 77, 77],
 [65, 67, 88, 77, 76],
 [36, 21, 41, 29, 25],
 [98, 77, 38, 40, 96]]

This tells me that when python copies the list 5 times, all it is doing is storing 5 pointers to your first list - then, when you change the values in that list, you are actually just changing the value in the first list and it gets reflected in all lists which point to that one.

Using your method, you can't update all the list independently.

Instead, I would suggest changing your list generation line to look more like this:

grid = [[0] * ncols for row in range(ncols)]

That should create 5 independent lists for you.

a_m0d