Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

elements being copied along a list in python

Tags:

python

list

class

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!

like image 557
Catherine Georgia Avatar asked Jan 23 '26 10:01

Catherine Georgia


1 Answers

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]]
like image 181
NPE Avatar answered Jan 25 '26 01:01

NPE



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!