I have a list of lists called hab acting as a 2D array. In this list of lists I am storing elements of a class called loc which is why I am not using a numpy array (it's not storing numbers).
I want to fill each element with a randomly picked 'loc' by looping through each element. However it seems that whenever I get to the end of a row, the program takes the final row element and puts it in all the other elements in that row. This means that I end up with the list of lists looking like this:
3 3 3 3 3
1 1 1 1 1
2 2 2 2 2
2 2 2 2 2
4 4 4 4 4
when actually I want all these numbers to be random (this is printing out a specific trait of each loc which is why it is numbers).
Here is the relevant bit of code:
allspec=[] # a list of species
for i in range(0,initialspec):
allspec.append(species(i)) # make a new species with new index
print 'index is',allspec[i].ind, 'pref is', allspec[i].pref
hab=[[0]*xaxis]*yaxis
respect = randint(0,len(allspec)-1)
for j in range(0,yaxis):
for k in range (0,xaxis):
respect=randint(0,len(allspec)-1)
print 'new species added at ',k,j,' is ', allspec[respect].ind
hab[k][j]=loc(k,j,random.random(),allspec[respect])
print 'to confirm, this is ', hab[k][j].spec.ind
for k in range (0,xaxis):
print hab[k][j].spec.ind
printgrid(hab,xaxis,yaxis)
print 'element at 1,1', hab[1][1].spec.ind
Within the loop, I am confirming that the element I have created is what I want it to be with the line print 'to confirm, this is ', hab[k][j].spec.ind and it is fine at this point. It is only when that loop is exited that it somehow fills every element on the row with the same thing. I don't understand!
The problem is here:
hab=[[0]*xaxis]*yaxis
As a result of the above statement, hab consists of yaxis references to the same list:
In [6]: map(id, hab)
Out[6]: [18662824, 18662824, 18662824]
When you modify hab[k][j], all other hab[][j] change too:
In [10]: hab
Out[10]: [[0, 0], [0, 0], [0, 0]]
In [11]: hab[0][0] = 42
In [12]: hab
Out[12]: [[42, 0], [42, 0], [42, 0]]
To fix, use
hab=[[0]*xaxis for _ in range(yaxis)]
Now each entry of hab refers to a separate list:
In [8]: map(id, hab)
Out[8]: [18883528, 18882888, 18883448]
In [14]: hab
Out[14]: [[0, 0], [0, 0], [0, 0]]
In [15]: hab[0][0] = 42
In [16]: hab
Out[16]: [[42, 0], [0, 0], [0, 0]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With