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

2024-05-15 17:54:44 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

这个想法是每隔一定的圈数复制“最强”的细胞。问题是这些单元格被复制的次数太多了;如果您运行代码几次,您肯定也会看到我所指的内容。你知道吗

我的怀疑是,我试图更改一个我正在迭代的列表,或者我在某个地方错误地引用了一个列表,但是我不能确定问题所在。你知道吗

任何帮助都将不胜感激。谢谢您!你知道吗


Tags: and代码inimport列表forifstatus
1条回答
网友
1楼 · 发布于 2024-05-15 17:54:44

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

尝试用断点debug代码。为了便于使用,没有什么比IPython pdb更好,尽管pdb - Python debuggerwinpdb也很有用。如果您正在使用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>提示符后键入help以获得命令列表。你知道吗

    基本命令是

    • n对于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将以iterable长度的多少来逐步完成列表理解。

  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):
    

希望你能明白。学习使用调试器要比让别人发现你的bug有更多的回报。至少,如果你能确定多余的重复开始出现的地方,那么你可以问一个更具体的问题,你会得到更好的答案。你知道吗

快乐的编码!你知道吗

相关问题 更多 >