1
for family in city.familyList:
    for member in family.membersList:
        if member.sex == "male":
            if member.status == "eligible":
                print "There were", len(family.membersList), "members of family", family.familyName
                family.membersList.remove(member)
                print "Now there are", len(family.membersList), "members of family", family.familyName
                member.status = "needs a wife"
                print member.firstName, member.status
                print "There were", len(city.familyList), "families"
                city.familyList.append(Family(member.lastName, member))
                print "Now there are", len(city.familyList), "families"

使用这段代码,我试图遍历家庭成员列表,找到 18 岁以上的男性,将他们从家庭中移除,并开始他们自己的家庭。如果我在循环末尾注释掉附加,它可以正常工作(当然,不会增加家庭的数量)。如果我执行附加,这就是它的样子:

Ticking Disan
There were 5 members of family Evnes
Now there are 4 members of family Evnes
Gregor needs a wife
There were 6 families
Now there are 7 families
There were 7 members of family Bhworth
Now there are 6 members of family Bhworth
Ewan needs a wife
There were 7 families
Now there are 8 families

debugger.run(setup['file'], None, None)
  File "C:\Users\Mark\Desktop\eclipse-SDK-3.7.2-win32\eclipse\plugins\org.python.pydev.debug_2.5.0.2012040618\pysrc\pydevd.py", line 1060, in run

pydev_imports.execfile(file, globals, locals) #execute the script
  File "C:\Users\Mark\workspace\WorldPop\WorldPop.py", line 610, in <module>
    main()
  File "C:\Users\Mark\workspace\WorldPop\WorldPop.py", line 74, in main
    done = menu()
  File "C:\Users\Mark\workspace\WorldPop\WorldPop.py", line 77, in menu
    genWorld()
  File "C:\Users\Mark\workspace\WorldPop\WorldPop.py", line 116, in genWorld
    dispWorld(oneWorld)
  File "C:\Users\Mark\workspace\WorldPop\WorldPop.py", line 135, in dispWorld
    displayTick(world)
  File "C:\Users\Mark\workspace\WorldPop\WorldPop.py", line 317, in displayTick
    calcMarriage(city)
  File "C:\Users\Mark\workspace\WorldPop\WorldPop.py", line 359, in calcMarriage
    for member in family.membersList:
TypeError: iteration over non-sequence

我意识到当 for 循环循环回到起点以搜索新的 memberList 时,问题就出现了,我只是不明白为什么执行附加会破坏循环。非常感谢任何见解。

4

2 回答 2

2

您要附加的新Family实例有一个membersList属性,但它不支持迭代(for/in)。这就是您收到此异常的原因。

即使在修复了这个问题之后,您也可以通过在迭代序列时修改序列来为自己准备好惊喜。尝试这个:

for family in city.familyList[:]:
    for member in family.membersList[:]:
        # ...

切片语法创建每个列表的[:]副本,因为它存在于循环的开头。对原始列表的修改不会影响副本,因此在循环执行期间不会有任何意外。

如果您确实需要在循环中包含在for循环中找到/创建的新项目for,我建议迭代一个Queue.Queue对象并将每个对象插入到该队列中进行探索。当没有新的探索时,队列将为空并且循环将停止。

于 2012-05-12T18:32:58.533 回答
1

一般来说,修改您正在迭代的集合是一个非常糟糕的主意(您既要删除又要family.membersList添加到city.familyList)。

根据您正在迭代的数据结构和迭代算法,更改迭代集合可能会导致项目被跳过或多次查看。我认为这在大多数情况下都是不安全的,除非文档明确说明。

于 2012-05-12T18:22:29.193 回答