1

the trick is:

IPython prompt:

In [1]: A = [ [] ] * 2

In [2]: A
Out[2]: [[], []]

In [3]: A[0].append(1)

In [4]: A
Out[4]: [[1], [1]]

Obvious, it's not my expected result, what's I want is [[1], []]. So why? I found no ref in the docs about python multiply sequence.

And is there any elegant(use no any explicit loop) ways to do that?

atupal
  • 16,404
  • 5
  • 31
  • 42

2 Answers2

4

A = [ [] ] * 2 creates a list with two references to the same list:

>>> A = [ [] ] * 2
>>> id(A[0])
24956880
>>> id(A[1])
24956880
>>> id(A[0]) == id(A[1])
True
>>>

Instead, you need to use a list comprehension:

>>> A = [[] for _ in xrange(2)]
>>> A
[[], []]
>>> A[0].append(1)
>>> A
[[1], []]
>>>

Note that, if you are on Python 3.x, you will need to replace xrange with range.

2

[ [] ] is an array containing (a reference to) a list. When you multiply it by 2, you get a list containing two references to the same list. Try this:

A = [[] for i in range(5)]

It will generate a new empty list for every tick of range.

There can't really be a no-loop version of this, because you really need to construct multiple lists; there can be no shortcut.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • No problem. I'm glad you've updated the answer though. :) – mgilson Dec 11 '13 at 03:37
  • 1
    The correction was good, but we really don't need to see the crossed-out old version - it's distracting. – Mark Ransom Dec 11 '13 at 04:00
  • He retracted the comments because you fixed the problem. I'll do the same if you want. If your own comments seem out of place now you can delete those yourself. – Mark Ransom Dec 11 '13 at 04:23