-3

I have the following piece of code as a problem.

list = [ [ ] ] * 5
print list
list[0].append(1)
print list

The first line prints [[][][][][]] which is what it should print but the second print gives

[[1][1][1][1][1]]

why does this happen? it is supposed to append only to the first list.

  • 1
    Not to answer your question, though you should avoid variable naming as built-in names...`list` is a built-in name – Iron Fist Jan 10 '16 at 15:20
  • `list` is a Python built-in name , dont use it for a variable name – ᴀʀᴍᴀɴ Jan 10 '16 at 15:20
  • alright i just wanted to make an example.this is not the exact code. – user5729542 Jan 10 '16 at 15:25
  • why am i being downvoted? – user5729542 Jan 10 '16 at 15:29
  • I can't give you a definitive answer on the downvotes (the close vote was obviously correct), but I can guess -- as it was, the title for this question was much too vague to be useful; there are lots of ways for things to "come out wrong", whereas a more definite description (for instance, "list append affecting multiple lists") would have meant that readers could tell what you were asking about without needing to click through. – Charles Duffy Jan 10 '16 at 15:42
  • 1
    As an aside, a close cousin to this bug is what happens when one passes a list (or other mutable object) as a default parameter to a function -- every time the function is called without that parameter being overridden, a reference to that exact same object is used. – Charles Duffy Jan 10 '16 at 15:45

2 Answers2

2

In

list = [ [] ] * 5

...you're creating five references to the same inner list. Thus, appending to one of them appends to them all.


Consider instead:

l = [ [] for _ in range(5) ]

...which constructs a new list for each element.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
0

Using id you can see that they refer to the same object.:

>>> l = [[]]*5
>>> for i in l:
    print id(i)


42277424
42277424
42277424
42277424
42277424
>>> 
>>> l[0].append(1)
>>> l
[[1], [1], [1], [1], [1]]
>>> id(1)
32851648
>>> for lst in l:
    for item in lst:
        print 'item : {0}, list : {1}'.format(id(item), id(lst))


item : 32851648, list : 42277424
item : 32851648, list : 42277424
item : 32851648, list : 42277424
item : 32851648, list : 42277424
item : 32851648, list : 42277424

As you can see, l actually have five same references to one object, []. So if you change anyone of them, you will see the same effect on the rest items

Iron Fist
  • 10,739
  • 2
  • 18
  • 34