List & Object Duplication Issues in Python

余生长醉 提交于 2019-12-13 04:47:30

问题


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!


回答1:


I know this isn't exactly the answer the OP was looking originally looking for, but it might be the correct answer, and if the OP manages to find the issue, then maybe they will think it is the correct answer too.

Try to debug the code with breakpoints. For ease of use nothing beats IPython pdb, although pdb - Python debugger, and winpdb are also useful. If you are using Spyder or PyDev plugin for eclipse debugging is built into the graphical user interface - just set your breakpoints and go.

For your code:

  1. Install Ipdb and its dependencies (IPython, &c.)
  2. From the system command line you can use the handy ipdb script.

    ~ $ 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. Commands are the same as pdb and for any debugger. Type help after the ipdb> prompt for a list of commands.

    The basic commands are

    • n for next to execute the current line and step to the next,
    • s or step to execute the next line of a called object, such as a function or class constructor or method,
    • r to return to the caller,
    • b to set a breakpoint
    • c to continue execution until the next breakpoint and
    • q to quit or exit

    Get more help by typing help <cmd>. EG

    ipdb> help r
    r(eturn)
    Continue execution until the current function returns.
    
  4. Set a breakpoint in your code where you think the trouble might be and step through it.

    ipdb> b 67
    Breakpoint 1 at ~\species.py:67
    
  5. You can use Python commands and examine variables with few restrictions - retval, rv and any of the ipdb commands will return the result of that ipdb call - so use vars()['<varname>'] instead.

  6. List comprehensions in ipdb are like for-loops, and so n will step through the list comprehension as many times as the length of the iterable.

  7. Hit enter/return key to repeat the last ipdb command. 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. Step into a function to see what it does

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

Hopefully you get the idea. Learning to use a debugger is going to have more payback than having someone else spot your bug. At the very least, if you can pinpoint where the extra duplicates start appear, then you can ask a more specific question and you will get better answers.

Happy coding!



来源:https://stackoverflow.com/questions/19145512/list-object-duplication-issues-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!