无法正确迭代我的列表

发布于 2024-12-11 16:07:44 字数 1517 浏览 0 评论 0原文

奇怪的是,我正在使用内置的Python迭代Oo

我有一个名为Card的类。除其他外,卡片还具有名称和符号列表(字符串)。

这是我的一段代码(所有打印都是为了调试目的)

    # This prints all the names of the cards in the deck before the iteration.
    print(str([card.name for card in self.thegame.game_deck.deck[0]]))

    for card in self.thegame.game_deck.deck[0]:
        if 'CASTLE' not in card.symbols: 
            self.thegame.game_deck.deck[0].remove(card)
            print(card.name + ' was removed')
        else: print(card.name + ' was not removed')

    # This prints all the names of the cards in the deck after the iteration.                
    print(str([card.name for card in self.thegame.game_deck.deck[0]]))

奇怪的是,这是标准输出上的输出:

['Writing', 'Tools', 'The Wheel', 'Sailing', 'Pottery', 'Oars', 'Mysticism', 'Me
talworking', 'Masonry', 'Domestication', 'Code of Laws', 'Clothing', 'City State
s', 'Archery', 'Agriculture']

Writing was removed
The Wheel was not removed
Sailing was removed
Oars was not removed
Mysticism was not removed
Metalworking was not removed
Masonry was not removed
Domestication was not removed
Code of Laws was removed
City States was not removed
Archery was not removed
Agriculture was removed


['Tools', 'The Wheel', 'Pottery', 'Oars', 'Mysticism', 'Metalworking', 'Masonry'
, 'Domestication', 'Clothing', 'City States', 'Archery']

正如您可以清楚地看到的,第一个列表中有名称(具体来说:“工具”、“陶器” ,“服装”)

在输出的第二部分中没有打印任何内容,实际上它们都留在列表中(顺便说一句,所有三个符号中都有“CASTLE”,应该删除)。

有人能看到我错过了什么吗?

The strange thing is that I'm using Python built in iteration O.o

I have a class called Card. Card has, among other things, a name and a list of symbols (string).

Here is a piece of my code (all the prints are for debugging purposes)

    # This prints all the names of the cards in the deck before the iteration.
    print(str([card.name for card in self.thegame.game_deck.deck[0]]))

    for card in self.thegame.game_deck.deck[0]:
        if 'CASTLE' not in card.symbols: 
            self.thegame.game_deck.deck[0].remove(card)
            print(card.name + ' was removed')
        else: print(card.name + ' was not removed')

    # This prints all the names of the cards in the deck after the iteration.                
    print(str([card.name for card in self.thegame.game_deck.deck[0]]))

And strangely enough, this is the output on stdout:

['Writing', 'Tools', 'The Wheel', 'Sailing', 'Pottery', 'Oars', 'Mysticism', 'Me
talworking', 'Masonry', 'Domestication', 'Code of Laws', 'Clothing', 'City State
s', 'Archery', 'Agriculture']

Writing was removed
The Wheel was not removed
Sailing was removed
Oars was not removed
Mysticism was not removed
Metalworking was not removed
Masonry was not removed
Domestication was not removed
Code of Laws was removed
City States was not removed
Archery was not removed
Agriculture was removed


['Tools', 'The Wheel', 'Pottery', 'Oars', 'Mysticism', 'Metalworking', 'Masonry'
, 'Domestication', 'Clothing', 'City States', 'Archery']

As you can clearly see, there are names in the first list (specifically: 'Tools', 'Pottery', 'Clothing')

That nothing was print about in the second part of the output, and indeed they are left in the list (all three, btw, have 'CASTLE' in they symbols and should be removed).

Can someone see what am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

日记撕了你也走了 2024-12-18 16:07:45

当您迭代列表时,不应从列表中删除项目。

要么迭代列表的副本

for card in self.thegame.game_deck.deck[0][:]:
                                          ^^^ copies the list

或者使用要保留的项目创建一个新列表,然后重新分配它:

game_deck = self.thegame.game_deck
game_deck.deck[0] = [card for card in game_deck.deck[0] if 'CASTLE' in card.symbols]

You shouldn't remove items from a list while you iterate over it.

Either iterate over a copy of the list:

for card in self.thegame.game_deck.deck[0][:]:
                                          ^^^ copies the list

Or create a new list with the items you want to keep and then re-assign it:

game_deck = self.thegame.game_deck
game_deck.deck[0] = [card for card in game_deck.deck[0] if 'CASTLE' in card.symbols]
铁憨憨 2024-12-18 16:07:45

您正在修改正在迭代的列表。这是一个坏主意。相反,请将您确实想要保留的列表附加到单独的列表中,并在最后将其重新分配回卡片。

You're modifying the list that you're iterating through. This is a bad idea. Instead, append the ones you do want to keep to a separate list, and reassign that back to the card at the end.

画骨成沙 2024-12-18 16:07:45

您将从要迭代的列表中删除项目。使用具有 CASTLE 图标的卡片创建一个新列表,而不是删除具有该图标的卡片。

You're removing items from the list upon which you're iterating. Create a new list with cards that have the CASTLE icon instead of removing these that have the icon.

就是爱搞怪 2024-12-18 16:07:45

详细说明执行此操作时会发生什么:

In [99]: l = range(5)

In [100]: for i in l:       
    l.remove(i)
    print list(enumerate(l))
   .....:     
   .....:     
[(0, 1), (1, 2), (2, 3), (3, 4)]
[(0, 1), (1, 3), (2, 4)]
[(0, 1), (1, 3)]

当您更改列表时,您正在更改引用哪个项目的索引,如上面列表中的值 4 所示。

To elaborate on what happens when you do this:

In [99]: l = range(5)

In [100]: for i in l:       
    l.remove(i)
    print list(enumerate(l))
   .....:     
   .....:     
[(0, 1), (1, 2), (2, 3), (3, 4)]
[(0, 1), (1, 3), (2, 4)]
[(0, 1), (1, 3)]

As you change the list, you're changing what index refers to which item, as you can see with the value 4 in the list above.

没有心的人 2024-12-18 16:07:45

迭代时删除的另一种常见替代方法是将项目标记为待删除(改变列表中的值但不更改列表长度),然后进行第二次高速传递以过滤掉不需要的卡片:

# This prints all the names of the cards in the deck before the iteration.
print(str([card.name for card in self.thegame.game_deck.deck[0]]))

for i, card in enumerate(self.thegame.game_deck.deck[0]):
    if 'CASTLE' not in card.symbols: 
        self.thegame.game_deck.deck[0][i] = None
        print(card.name + ' was marked to be removed')
    else: print(card.name + ' was not removed')
# This does the actual removal
self.thegame.game_deck.deck[0][:] = filter(None, self.thegame.game_deck.deck[0])

# This prints all the names of the cards in the deck after the iteration.                
print(str([card.name for card in self.thegame.game_deck.deck[0]]))

Another common alternate to removing-while-iterating is to mark items for pending deletion (mutating the value in the list but not changing the list length) and then making a second high-speed pass to filter-out the unwarranted cards:

# This prints all the names of the cards in the deck before the iteration.
print(str([card.name for card in self.thegame.game_deck.deck[0]]))

for i, card in enumerate(self.thegame.game_deck.deck[0]):
    if 'CASTLE' not in card.symbols: 
        self.thegame.game_deck.deck[0][i] = None
        print(card.name + ' was marked to be removed')
    else: print(card.name + ' was not removed')
# This does the actual removal
self.thegame.game_deck.deck[0][:] = filter(None, self.thegame.game_deck.deck[0])

# This prints all the names of the cards in the deck after the iteration.                
print(str([card.name for card in self.thegame.game_deck.deck[0]]))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文