2012-12-10 43 views
2

我有一個名爲hab的列表充當二維數組。在這個列表中,我存儲了一個名爲loc的類的元素,這就是爲什麼我不使用numpy數組(它不存儲數字)。正在python中沿着列表複製的元素

我想通過循環每個元素來用隨機選取的'loc'填充每個元素。但是,似乎只要我到達行的末尾,程序就會獲取最後一行元素,並將其放入該行的所有其他元素中。這意味着,我結束了尋找這樣的列表清單:

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 

的時候其實我想所有這些數字是隨機的(這是打印出每個loc這是一個特定性狀爲什麼它是數字) 。

這裏是代碼的相關位:

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 

在循環中,我確認我已創建的元素是什麼,我想這是與線print 'to confirm, this is ', hab[k][j].spec.ind,它是罰款在這一點上。只有當循環退出時,它纔會以某種方式填充同一行上的每一個元素。我不明白!

+0

您應該在這裏使用['random.choice'](http://docs.python.org/2/library/random.html#random.choice),或者甚至可能使用['random.sample'](http ://docs.python.org/2/library/random.html#random.sample)。 –

+0

你可以顯示你的'printgrid'功能嗎?很可能你實際上是在創建列表,但是打印錯誤。 – jdotjdot

回答

8

的問題是在這裏:

hab=[[0]*xaxis]*yaxis 

由於上述語句的結果,habyaxis引用相同的列表

In [6]: map(id, hab) 
Out[6]: [18662824, 18662824, 18662824] 

當您修改hab[k][j],所有其他hab[][j]也變:

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]] 

要修復,使用

hab=[[0]*xaxis for _ in range(yaxis)] 

現在的hab每個條目是指一個單獨的列表:

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]] 
+0

謝謝!你能告訴我爲什麼我的定義方式不起作用嗎? –

+0

@CatherineGeorgia:請參閱擴展的答案。 – NPE

3

對方回答解釋了什麼是錯的,但我想用提供一個更清晰的實現你可能沒有意識到的Python特性。

import random 
from pprint import pprint 

class species(object): 
    def __init__(self, ind): 
     self.ind = ind 
     self.perf = ind 

def makespecies(n): 
    # using list comprehensions, we don't need a for-loop 
    # we could also have said `map(species, range(n))` 
    return [species(i) for i in range(n)] 


def makegrid(w, h, species): 
    # rather than initialize empty lists, we create a new list 
    # for each row as we go. This avoids the bug in your code 
    # while also being much easier to read. 
    return [[random.choice(species) for i in range(w)] for j in range(h)] 

def printgrid(grid, attr): 
    pprint([[getattr(e, attr, None) for e in row] for row in grid]) 

speclist = makespecies(10) 
grid = makegrid(5,5,speclist) 
printgrid(grid, 'ind') 

這將打印出類似這樣:

[[5, 8, 6, 8, 9], 
[9, 3, 3, 1, 3], 
[3, 8, 1, 5, 5], 
[7, 4, 7, 1, 7], 
[4, 3, 3, 1, 9]] 

還要注意的是,如果你使用大型陣列工作或對他們做面向矩陣運算,你應該考慮使用numpy的。你可以創建一個「主」嵌套數組(如這個),它將你的物種對象作爲原始數據,然後用它來數組操作的數組numpy。

+0

這看起來比我擁有的東西更加優雅,非常感謝。 –