列表& Python中的对象复制问题

时间:2013-10-02 19:46:05

标签: python list loops duplicates

之前我曾问过一个涉及循环和列表的问题,并收到了一些很好的反馈。不幸的是,我遇到了一个我自己似乎无法解决的新问题。我为大块代码道歉:

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

这个想法是每隔一定数量的回合复制“最强”的细胞。问题是这些细胞被复制的次数太多了;如果你运行代码几次,你一定会看到我所指的是什么。

我的怀疑是我正在尝试更改我正在迭代的列表,或者我在某处错误地引用了某个列表,但我无法查明问题点。

非常感谢任何和所有帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

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

尝试使用断点debug代码。为了便于使用,虽然IPython pdbpdb - Python debugger也很有用,但没有什么比winpdb好。如果您使用SpyderPyDev插件进行eclipse调试内置于图形用户界面中 - 只需设置断点即可。

代码:

  1. 安装Ipdb及其依赖项(IPython,& c。)
  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>提示符后输入帮助以获取命令列表。

    基本命令是

    • n next 执行当前行并跳到下一行,
    • s step 执行被调用对象的下一行,例如函数或类构造函数或方法,
    • r 返回给来电者
    • b设置breakpoint
    • c 继续执行,直到下一个断点和
    • q 退出退出

    点击help <cmd>获取更多帮助。 EG

    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. 按Enter / return键重复上一个ipdb命令。 EG

    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):
    
  9. 希望你明白了。学习使用调试器比其他人发现你的bug有更多的回报。至少,如果你能确定出现多余重复的位置,那么你可以提出一个更具体的问题,你会得到更好的答案。

    快乐的编码!