1

Possible Duplicate:
Simple python code about double loop

I'm stuck with the well known problem of changing 1 item in a list of lists. I need to use a fixed size list of list.

If I use:

In [21]: a=[[2]*2]*3

In [22]: a
Out[22]: [[2, 2], [2, 2], [2, 2]]

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

In [24]: a
Out[24]: [[1, 2], [1, 2], [1, 2]]

But if I define the list of list in the following way, it works:

In [26]: a = [
   ....: [2,2],
   ....: [2,2],
   ....: [2,2],
   ....: ]

In [27]: a   
Out[27]: [[2, 2], [2, 2], [2, 2]]

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

In [29]: a
Out[29]: [[1, 2], [2, 2], [2, 2]]

To me line 22 and 27 looks identical. So which is the difference?

Can someone explain me how to go around this problem and, in particular, how to change a code that change a single item of a list of list? If this is not possible, any suggestion to move to a different data structure allowing that? thanks

Community
  • 1
  • 1
  • sorry - but I was going to show how two different ways to generate an array brings to the same output. And however I understand there is NO WAY to sort out the system with a fixed size list of lists... – user1640950 Sep 02 '12 at 16:02

1 Answers1

0

There is a fundamental difference in the 2 ways you defined the matrix in both code samples. In the first (line 21) when you multiply the outer list by 3 you actually multiply the references to the inner list.

Here's a parameterized example:

a = [2,2]
b = [a] * 3
b => [a, a, a] => [[2,2], [2,2], [2,2]]

As you can see the numerical representation of b is what you would expect, but it actually contains 3 references to a. So if you change either of the inner lists, they all change, because they are actually the same list.

Instead of multiplication you need to clone the lists doing something like this

new_list = old_list[:]

or

new_list = list(old_list)

In the case of nested lists, this can be done using loops.

Avihu Turzion
  • 3,284
  • 4
  • 25
  • 34
  • thanks, but how to write something that works and actually change only the item I need to change? I'm quite a newbie (at least in the use of list..). – user1640950 Sep 02 '12 at 16:00
  • @user1640950 use this `a=[[2]*2 for _ in range(3)]` – Ashwini Chaudhary Sep 02 '12 at 16:06
  • 1
    @user1640950 thank us by accepting any of the answers. see [Accepting Answers: How does it work?](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235) – Ashwini Chaudhary Sep 02 '12 at 16:15