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 に答える