为什么附加到列表会破坏我的for循环? (蟒蛇)

时间:2012-05-12 18:07:35

标签: python loops append

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时问题就出现了,我只是不明白为什么执行append会破坏循环。非常感谢任何见解。

2 个答案:

答案 0 :(得分:2)

您要追加的新Family实例具有membersList属性,但它不支持迭代(for / in)。这就是你收到这个例外的原因。

即使在解决了这个问题之后,你也可以通过在迭代它们的同时修改序列来为自己设置惊喜。试试这个:

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

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

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

答案 1 :(得分:1)

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

根据您要迭代的数据结构以及迭代算法,更改迭代集合可能会导致项目被跳过或被多次看到。我认为这在大多数时候都是不安全的,除非文档明确另有说法。