0

I had asked a question earlier that involved loops and lists and received some great feedback. Unfortunately, I've run into a new issue that I just can't seem to solve by myself. My apologies for the large block of code:

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

The idea is to duplicate the "strongest" cells every certain number of turns. The problem is that these cells are being copied too many times; if you run the code a few times, you're bound to see what I'm referring too.

My suspicion is that I'm trying to change a list that I'm iterating over or that I'm somehow incorrectly referencing a list somewhere, but I can't pinpoint the problem spot.

Any and all help would be greatly appreciated. Thank you!

4

1 回答 1

0

我知道这不是 OP 最初寻找的答案,但它可能是正确的答案,如果 OP 设法找到问题,那么他们可能也会认为这也是正确的答案。

尝试使用断点调试代码。为了易于使用,没有什么比IPython pdb更好了,尽管pdb - Python debuggerwinpdb也很有用。如果您使用SpyderPyDev插件进行Eclipse调试,则图形用户界面中内置 - 只需设置断点即可。

对于您的代码:

  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>在命令列表提示后键入帮助。

    基本命令是

    • nfor next执行当前行并跳到下一个,
    • 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命令都将返回该ipdb调用的结果 - 所以请vars()['<varname>']改用。

  6. 列表推导ipdb类似于 for 循环,因此n将按照可迭代的长度多次执行列表推导。

  7. 按回车键重复上一个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 回答