44

I've encountered what I think is a strange behavior in Python, and I'd like somebody to explain it if possible.

I've created an empty 2D list

listy = [[]]*3

print listy

[[], [], []]

The following works as I'd expect:

listy[1] = [1,2] yields [[], [1,2], []]

listy[1].append(3) yields [[], [1,2,3], []]

However, when I append to one of the empty lists, python appends to ALL of the sublists, as follows:

listy[2].append(1) yields [[1], [1,2,3], [1]].

Can anyone explain to me why this behavior occurs?

heltonbiker
  • 26,657
  • 28
  • 137
  • 252
David M
  • 710
  • 1
  • 8
  • 14
  • 4
    I wonder how many times per month this gets asked. Surely this is one of the all-time most frequently asked questions about Python (and not just on Stack Overflow). From the FAQ in the official Python docs: [How do I create a multidimensional list?](http://docs.python.org/faq/programming.html#how-do-i-create-a-multidimensional-list) – John Y Oct 12 '11 at 20:04

3 Answers3

71

You haven't created three different empty lists. You've created one empty list, and then created a new list with three references to that same empty list. To fix the problem use this code instead:

listy = [[] for i in range(3)]

Running your example code now gives the result you probably expected:

>>> listy = [[] for i in range(3)]
>>> listy[1] = [1,2]
>>> listy
[[], [1, 2], []]
>>> listy[1].append(3)
>>> listy
[[], [1, 2, 3], []]
>>> listy[2].append(1)
>>> listy
[[], [1, 2, 3], [1]]
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
18

[[]]*3 is not the same as [[], [], []].

It's as if you'd said

a = []
listy = [a, a, a]

In other words, all three list references refer to the same list instance.

recursive
  • 83,943
  • 34
  • 151
  • 241
-3

Came here to see how to append an item to a 2D array, but the title of the thread is a bit misleading because it is exploring an issue with the appending.

The easiest way I found to append to a 2D list is like this:

list=[[]]

list.append((var_1,var_2))

This will result in an entry with the 2 variables var_1, var_2. Hope this helps!

D.Dimanov
  • 135
  • 1
  • 6