1

I was working on some problem and came across this.

Python code

row=[]
col=[]
init=[-1,-1]

Now I append this init to row and col.

row.append(init)
row.append(init)

col.append(init)
col.append(init)

Therefore row = [[-1,-1],[-1,-1]] and col = [[-1,-1],[-1,-1]]

Now when i change init[0] = 9 my row and col becomes row = [[9,-1],[9,-1]] and col = [[9,-1],[9,-1]]

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
Sagar Rakshe
  • 2,682
  • 1
  • 20
  • 25
  • You might want to say why you think this is abnormal, because this probably looks normal to most python programmers. – wrgrs Feb 16 '13 at 18:26
  • 1
    @wrgrs I'm a Python programmer, and while the behavior the program exhibits is perfectly normal (expected, even) to me, I have no trouble imagining why OP considers this abnormal (expecting a copy to be made, or more generally expecting call by value instead of call by sharing). –  Feb 16 '13 at 18:28

2 Answers2

6

This happens because you store the same reference to the object init over and over. So when you modify the object everyone sees it.

You could try appending copies of the list instead. One way for example could be:

row.append(list(init))

There's more than one way to clone a list.

Community
  • 1
  • 1
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 1
    +1, though I think list(init) is less cryptic for newcomers :) – salezica Feb 16 '13 at 18:15
  • Agreed, as an explanation, `[:]` takes a slice from the start to the end of the list, effectively copying it. `list()` will do the same job more clearly. – Gareth Latty Feb 16 '13 at 18:16
1

This may be of help explaining why

http://www.jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

  • 1
    It is, and it's great at it, but if you have nothing else to say, [it's not considered a good answer](http://meta.stackexchange.com/q/8231) -- I think a comment is a better place to do this. I know, you're new and aren't even allowed to post comments yet, just for the future. –  Feb 16 '13 at 18:24