Ben McCormack Ben McCormack - 1 month ago 10
Python Question

Assign value to an individual cell in a two dimensional python array

Let's say I have the following empty two dimensional array in Python:

q = [[None]*5]*4


I want to assign a value of
5
to the first row in the first column of
q
. Instinctively, I do the following:

q[0][0] = 5


However, this produces:

[[5, None, None, None, None],
[5, None, None, None, None],
[5, None, None, None, None],
[5, None, None, None, None]]


The first element of every array is being initialized to
5
, where I thought only the first element of the first array would get the update. I have two questions:


  1. Why is Python initializing the first value of every array and not just the first one?

  2. Is there a better way to accomplish what I'm trying to do?


Answer

This doesn't do what you hoped.

q = [[None]*5]*4

It reuses list objects multiple times. As you can see when you made a change to one cell, which was in a reused list object.

A single list with a value of [None] is used five times.

A single list with a value of [[None]*5] is used four times.

q = [ [ None for i in range(5) ] for j in range(4) ]

Might be more what you're looking for.

This explicitly avoids reusing a list object.

80% of the time, a dictionary is what you really wanted.

q = {}
q[0,0]= 5

Will also work. You don't start with a pre-defined grid of None values. But it's rare to need them in the first place.

In Python 2.7 and higher, you can do this.

q = { (i,j):0 for i in range(5) for j in range(4) }

That will build a grid indexed by 2-tuples.

{(0, 1): 0, (1, 2): 0, (3, 2): 0, (0, 0): 0, (3, 3): 0, (3, 0): 0, (3, 1): 0, (2, 1): 0, (0, 2): 0, (2, 0): 0, (1, 3): 0, (2, 3): 0, (4, 3): 0, (2, 2): 0, (1, 0): 0, (4, 2): 0, (0, 3): 0, (4, 1): 0, (1, 1): 0, (4, 0): 0}