0

以前、ループとリストに関する質問をして、素晴らしいフィードバックをいくつか受け取りました。残念ながら、自分では解決できないように見える新しい問題に遭遇しました。コードの大きなブロックについてお詫び申し上げます。

import random
from pprint import pprint

petri_dish = []
lst = [y for y in petri_dish if y.status == 1]

turn = 1

class Species:
    #__init__,relocate, fight, and target methods

for n in range(20):
    petri_dish.append(Species(n,0,0,0,0,1))

def reproduce():
    class Offspring(Species):
        pass
    for z in list(petri_dish):
        if z.status == 1 and z.life >= 200:
            petri_dish.append(Offspring('A'+str(z.name),0,0,0,0,1))

def move_around():
    for x in list(petri_dish):
        if turn % 2000 == 0:
            reproduce()
        x.relocate()
        x.target()

while len([y for y in petri_dish if y.status == 1]) > 1:
    turn += 1     
    move_around()

for x in [y for y in petri_dish if y.status == 1]:
    pprint(vars(x))

print turn

アイデアは、特定のターン数ごとに「最強」のセルを複製することです。問題は、これらのセルが何度もコピーされていることです。コードを数回実行すると、私が言及していることもわかるはずです。

私の疑いは、繰り返し処理しているリストを変更しようとしているか、どこかでリストを誤って参照しているのではないかと考えていますが、問題の場所を特定することはできません。

ありとあらゆる助けをいただければ幸いです。ありがとうございました!

4

1 に答える 1

0

これは、OPが最初に探していた答えではないことはわかっていますが、正しい答えである可能性があり、OPが問題を見つけることができれば、それも正しい答えだと思うでしょう。

ブレークポイントを使用してコードをデバッグしてみてください。pdb - Python debuggerwinpdbも便利ですが、使いやすさの点でIPython pdbに勝るものはありません。Eclipseデバッグ用のSpyderまたはPyDevプラグインを使用している場合は、グラフィカル ユーザー インターフェイスに組み込まれています - ブレークポイントを設定するだけです。

あなたのコードのために:

  1. Ipdb とその依存関係 (IPython など) をインストールします。
  2. ipdbシステム コマンド ラインから、便利なスクリプトを使用できます。

    ~ $ ipdb --help
    
    usage: ipdb.py scriptfile [arg] ...
    ~ $ ipdb species.py args
    > ~\species.py(1)<module>()
    ---> 1 import random
         2 from pprint import pprint
         3
    
    ipdb>
    
  3. pdbコマンドは、どのデバッガーでも同じです。ipdb>コマンドのリストのプロンプトの後に help と入力します。

    基本的なコマンドは

    • nnextは現在の行を実行し、次の行に進みます。
    • sまたは、関数またはクラスのコンストラクターまたはメソッドなど、呼び出されたオブジェクトの次の行を実行するステップ
    • r呼び出し元に戻るには、
    • bを設定するbreakpoint
    • c次のブレークポイントまで実行を継続し、
    • qやめる、または終了する

    と入力すると、さらにヘルプが表示されますhelp <cmd>。例えば

    ipdb> help r
    r(eturn)
    Continue execution until the current function returns.
    
  4. 問題があると思われるコード内にブレークポイントを設定し、ステップ実行します。

    ipdb> b 67
    Breakpoint 1 at ~\species.py:67
    
  5. Python コマンドを使用して、ほとんど制限なしで変数を調べることができます。またretvalrvどのコマンドもその呼び出しipdbの結果を返すため、代わりに使用してください。ipdbvars()['<varname>']

  6. のリスト内包ipdb表記は for ループに似ているためn、イテラブルの長さと同じ回数だけリスト内包表記をステップ実行します。

  7. Enter/Return キーを押して、最後のipdbコマンドを繰り返します。例えば

    ipdb> n
    > ~\species.py(67)<module>()
         66
    1--> 67 while len([y for y in petri_dish if y.status == 1]) > 1:
         68     turn += 1
    
    ipdb>
    > ~\species.py(67)<module>()
         66
    1--> 67 while len([y for y in petri_dish if y.status == 1]) > 1:
         68     turn += 1
    
    ipdb>
    > ~\species.py(69)<module>()
         68     turn += 1
    ---> 69     move_around()
         70
    
    ipdb> turn
    2
    
  8. 関数にステップインして、その機能を確認する

    ipdb> s
    --Call--
    > ~\species.py(60)move_around()
         59
    ---> 60 def move_around():
         61     for x in list(petri_dish):
    

うまくいけば、あなたはアイデアを得る。デバッガーの使い方を学ぶことは、誰かにバグを見つけてもらうよりも多くの見返りがあります。少なくとも、余分な重複が表示される場所を特定できれば、より具体的な質問をすることができ、より適切な回答が得られます。

ハッピーコーディング!

于 2013-10-02T20:23:39.443 に答える