Could someone explain this multidimensional list behaviour?

Donn Cave donn at drizzle.com
Fri Nov 23 13:17:22 EST 2001


Quoth lrl at ou.edu (L):
...
| >>> spam = [[0] * 3] * 3
| >>> spam
| [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
| >>> spam[0][1] = 1
| >>> spam
| [[0, 1, 0], [0, 1, 0], [0, 1, 0]]
|
| I was expecting after making the assignment to get this:
| [[0, 1, 0], [0, 0, 0], [0, 0, 0]]

Because python does the initial assignment the easy way -
compute [0] * 3, then use that in [result] * 3.  After all,
you'd be very surprised if it didn't come out the same when
written in two statements.  Writing it that way just makes
it clearer that all three elements of the larger list are
references to the same object.

| After flipping through my O'Reilly I know it has to do with the *
| operator, but don't know how otherwise allocate an n x n "array" type
| of structure beforehand with each element having a unique pointer,
| without using some sort of ridiculous two loop setup and appends like
| the following.
|
| >>> spam = []
| >>> for y in range(10):
| 	inner = []
| 	for x in range(10):
| 		inner.append(0)
| 	spam.append(inner)
| 	del inner

That's overkill.  The inside list was OK, because when you write
inner[1] = 1, you don't care what object was there before, you're
replacing it with the assignment (or rather setitem.)  You only
need distinct objects when you want to modify them.

	Donn Cave, donn at drizzle.com



More information about the Python-list mailing list