6

I am building a list of lists. I am reading the elements from an input file. I am reading in each line in the file as a string-single-element to a sub-list in the list. First, I created the list of lists:

>>> b = [[]] * 5

However, when I tried to append an item, I got the following:

>>> b[1].append("abc")
>>> b
[ ['abc'], ['abc'], ['abc'], ['abc'], ['abc'])

Why does append change all the sub-lists? Is insert() better in this situation?

Concerned_Citizen
  • 6,548
  • 18
  • 57
  • 75

3 Answers3

10

When you do [[]] * 5 it is a list of same objects (empty lists here) repeated 5 times.

You can check it by:

>>> b = [[]] *5

>>> b
[[], [], [], [], []]

>>> id(b[0])
140588316211896

>>> id(b[1])
140588316211896

What you would need to do is:

>>> b = [[] for i in range(5)]
>>> b[0].append('abc')
>>> b
[['abc'], [], [], [], []]

In case of [[] for i in range(5)], in each loop a new empty list object is created.

And insert would not be a good option here because insert is a O(n) operation whereas appending would be O(1).

Ankur Ankan
  • 2,953
  • 2
  • 23
  • 38
1

When you say

b = [[]] * 5

It creates 5 lists that all point to the same thing. If you print out the address of each element you'll find that they are the same.

So it wouldn't matter whether you used append or insert.

MxLDevs
  • 19,048
  • 36
  • 123
  • 194
  • No. Under the hood, the list is primarily composed of 5 references to the same unique list ``[ ]``, it means nothing to say a list points to a "thing" . A thing ? There's a word for that, it's "object". – eyquem Jan 02 '14 at 02:18
  • @eyquem Yes, it would not be accurate to say it is a list of lists, but I don't really see much of a difference between referring it as some "thing" or some "object". – MxLDevs Jan 02 '14 at 04:25
0

This is a FAQ. All 5 top-level list elements are pointing at the same list.

Check this out:

#!/usr/local/cpython-3.3/bin/python

if True:
    b = [[] for dummy in range(5)]
else:
    b = [[]] * 5

b[1].append("abc")

print(b)
dstromberg
  • 6,954
  • 1
  • 26
  • 27