2

hab2D 配列として機能するというリストのリストがあります。このリストのリストでは、呼び出されたクラスの要素を格納locしているため、numpy 配列を使用していません (数値を格納していません)。

各要素をループして、ランダムに選択された「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この時点では問題ありません。そのループが終了したときにのみ、行のすべての要素が同じもので埋められます。理解できない!

4

2 に答える 2

8

問題はここにあります:

hab=[[0]*xaxis]*yaxis

上記のステートメントの結果として、同じリストへの参照でhab構成されます。yaxis

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]]
于 2012-12-10T14:10:15.093 に答える
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 の使用を検討する必要があることに注意してください。種オブジェクトを生データとして持つ「マスター」のネストされた配列(このような)を作成し、vectorizeそれを数値演算用のnumpy配列にすることができます。

于 2012-12-10T14:33:02.273 に答える