6

Possible Duplicate:
Unexpected feature in a Python list of lists

I want to make a list of lists in Python, but apparently this doesn't work, as changing one number changes several. Why is this, and how can I fix it?

>>> a = [[0]*3]*4
>>> a[0][0] = 1
>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]
Community
  • 1
  • 1
Paul S.
  • 4,362
  • 10
  • 35
  • 52

4 Answers4

8

What you've discovered is a classic Python pitfall.

x = [0]*3 is a list. No problem there, but [x]*4 creates a list with 4 references to the exact same list x. So modifying the first element, x, also modifies the other elements as well.

Instead, if you do this:

In [193]: a = [[0]*3 for i in range(4)]

then you get 4 distinct items in the list:

In [194]: a[0][0] = 1

In [195]: a
Out[195]: [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
4

In Python, [x]*n creates a new list with n references to x. This is perfectly good to have if x is immutable (string, tuple, etc.), but it gets rather confusing if x is mutable since changes to one element affect x, and thus appear to affect all elements of the list.

So, the solution is to use a list comprehension to create n new things:

[x for _ in xrange(n)] # we use _ here as a "dummy variable"

In your case, it would look like

a = [[0]*3 for _ in xrange(4)]
nneonneo
  • 171,345
  • 36
  • 312
  • 383
1

Dont use *. Use list comprehension and create like:

>>> a = [[0 for i in range(3)] for j in range(4)]
>>> a[0][0] = 1
>>> a
[[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

See unutbu and nneonneo's answer for better explanation.

mshsayem
  • 17,557
  • 11
  • 61
  • 69
-1

When using * in list's it creates copies, so when you do a[0][0]=1 all other sub-list's copy this.

In order to fix this, use a generator expression to create your list.

IT Ninja
  • 6,174
  • 10
  • 42
  • 65