私はPythonを使って簡単な進化シミュレータを作っています。リストを反復処理中に要素を削除する効果はありますか?
ユニット/動物と食品の両方を格納するengine.All
と呼ばれるリストがあります。私はそれを繰り返し、私が動物に出くわしたら、もう一度それを繰り返して、彼が食べ物のどれかに衝突しているかどうかを調べる。
もしそうなら、私は彼のエネルギーを高め、食べ物を食べてフラグを立てて、それをから削除するために後で使用するtoRemove
リストに追加します。
これはコードですが、削除されたすべての冗長なもので:
def remove(l, who): #This should remove all the elements contained in who from the list l
offset = 0
for i in who:
l.pop(i + offset)
offset -= 1
return l
for ob in engine.All:
if ob.skip:
continue;
if ob.drawable:
ob.draw()
if isinstance(ob, Flatlander): #If it is an animal
#Do speed stuff
ob.energy -= decay #Lower its energy
for i in range(len(engine.All)): #Iterate through the list again
if collides(ob.pos, ob.r, engine.All[i].pos, engine.All[i].r) and isinstance(engine.All[i], Food) and ob.energy + engine.All[i].r < ob.r**2*3.14 and not engine.All[i].skip: #If it collides with a food piece, the food piece isn't about to be deleted and it can take the energy in (their maximum is defined by their radiuses)
ob.energy += engine.All[i].r #Increase the his energy
toRemove.append(i) #Add the food piece to the toRemove list
engine.All[i].skip = True #Flag it as skipped
if ob.energy < 0 and not ob.skip: #If its energy is 0 and if it isn't already about to be deleted
toRemove.append(engine.All.index(ob)) #Add it to the toRemove list
ob.skip = True #Flag it as skipped
engine.All = remove(engine.All, toRemove)
私はこれが動作しないことはほぼ確実だ、とこれを行うのは良い方法があること。私がとても確信しているのは、時には画面上で物事がちょうど「点滅」していることが突然消えて再び現れることです。また、「ゴースト」動物(コードではフラットランダーと呼ばれる)があるようですが、時には食品が永久に消えてしまうことがあるので、私はこれを結論づけます。
より効率的な方法をお勧めします。
答えをありがとう、これは動作するようです。ほんの1つの質問、Pythonにガベージコレクタがあるのですか、またはリストから削除した後にオブジェクトを 'del'する必要がありますか? – corazza
Pythonにガベージコレクションがあります。さまざまな実装(例えば、JythonとCPythonとの比較)は、発生時にちょっと違うかもしれませんが、そのことに頼ることができます。 –