0

So, I was working on Python for making List of arrays for my project work.

Sample code:

var0 = 0
var1 = 0
car = [0,0]
listitem = [car[:] for i in range(10)]
for i in range(10):
    car[0] = var0 + i + 1
    car[1] = var1 + i
    listitem[i] = car
print listitem

As the logic would suggest we would be expecting an output like:

[[1,0],[2,1],[3,2],[4,3],[5,4],[6,5],[7,6],[8,7],[9,8],[10,9]]

But the output comes as:

[[10,9],[10,9],[10,9],[10,9],[10,9],[10,9],[10,9],[10,9],[10,9],[10,9]]

I have come with a theory where the car array uses some pointers to the variable space.

Does anyone has a probable explanation for the same? Thank you

tmdavison
  • 64,360
  • 12
  • 187
  • 165
  • You're explicitly replacing all of the list copies you create with the original `car`. Move the shallow copy into the `for` loop. – jonrsharpe Dec 10 '15 at 13:37
  • 4
    No need for downvoting, but this has been asked many times before, e.g., [Python list of lists, changes reflected across sublists unexpectedly](http://stackoverflow.com/q/240178/2749397). – gboffi Dec 10 '15 at 13:41

3 Answers3

2

You're recycling the car variable in the loop, and so all your entries in listitem point to the same object.

var0 = 0
var1 = 0
car = [0,0]
listitem = [car[:] for i in range(10)]
for i in range(10):
    car = listitem[i]
    car[0] = var0 + i + 1
    car[1] = var1 + i
    listitem[i] = car
print listitem

See @simon-fraser's comment below for more info on why this is the case.

Community
  • 1
  • 1
mirosval
  • 6,671
  • 3
  • 32
  • 46
  • 1
    Is it worth mentioning `id()` to help the explanation? `for item in listitem: print(id(item))` shows they're all the same underlying object in the original post, and all different in yours – Simon Fraser Dec 10 '15 at 13:40
2

when you run this code 'listitem[i]=car',you assign the car's memory address to listitem[i], and the address for car is the same everytime. After the 10 times loop, all the subitem in listitem will point the same address. If you run below code :

 for i in range(10):
    car[0] = var0 + i + 1
    car[1] = var1 + i
    listitem[i] = car
    print hex(id(listitem[i]))

you will get the answer. At the last time the address for car saved with [10,9] so all the output is the same thing

Try this one :

  for i in range(10):
    listitem[i]=[a,b]=[var0 + i + 1,var1 + i]
MikeZhang
  • 327
  • 2
  • 10
0

There is actually no need to initialise all the elements of listitem as you can append to it. There is also no need to use a variable car as you can immediately store the items you create in listitem

var0 = 0
var1 = 0
listitem = []
for i in range(10):
    listitem.append([var0 + i + 1, var1 + i])
print listitem
Dirk Horsten
  • 3,753
  • 4
  • 20
  • 37