为什么在OO设置中迭代时不能删除列表元素?

2024-05-18 10:16:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我的情况如下:我正在实施21点。我有纸牌、手牌、牌手、牌组和游戏的课程。主要的游戏对象存储玩家和一副牌,而玩家存储的手存储卡。你知道吗

我经常这样做。在这个例子中,我把最初的牌发给每个玩家。你知道吗

num_cards = 2
for player in self.players:
    new_hand = Hand()
    for i in range(num_cards):
        new_hand.add_card(self.deck.get_next_card())
    player.assign_hand(new_hand)

这项工作非常出色。我现在的问题是,我希望从玩家的一组手牌中删除一只手牌(玩家可以在21点中拆分,从而生成多只手牌)。在下面的函数中,我打算遍历每个玩家的手。如果手的值大于21,我想删除手。(请注意,下面的remove()功能通常在Player类中执行,通过名为fold\u hand()的Player方法调用。我也遇到了同样的问题,所以为了便于解释,我将代码移到了更明显的地方。)

for player in self.players:
    for hand in player.hands:
        if hand.smallest_value() > 21:
            player.hands.remove(hand)

这不管用。为了清楚起见,我可以在remove()行之前打印出手,而在remove()行之后不会打印出来。也就是说,它似乎被移除了。然而,在下一轮比赛中,手又回来了。因此玩家的手每转一圈都会变大。你知道吗

上面的代码位于Game类中名为validate\u player\u hands()的函数中。这个函数是从一个名为播放.py,它的存在是为了开始/结束游戏并促进主要的游戏循环。因此,验证\u player \u hands()的唯一调用是播放.py文件,一个缩进,在游戏循环中。我叫:

game.validate_player_hands()

我也尝试过找到手的索引并使用'del'关键字,但结果是一样的。你知道吗

为什么列表元素(列表中的手对象)称为玩家手)当它看起来像已被删除时删除失败?你知道吗

提前谢谢

帕拉贡


Tags: 对象函数inself游戏newfor玩家
3条回答

如何使用一个简单的列表理解消除手:

for player in self.players:
    player.hands = [hand for hand in player.hands if hand.smallest_value() <= 21]

编辑

带过滤器:

for player in self.players:
    player.hands = filter(lambda x: x.smallest_value() <= 21, player.hands)

您将需要执行以下操作:

newList = hands[:]   
for hand in newList:  
    if hand.smallest_value() > 21:  #your code here
            player.hands.remove(hand)

这允许您在对要修改的列表进行迭代时复制该列表,从而避免Mihai提到的“树杈”场景。你知道吗

创建一个副本并使用与对象长度相关的索引遍历对象。用0设置要删除的每个元素,然后过滤指针以清除零。你知道吗

for player in self.players:
    for hand_idx in range(len(player.hands)):
        if player.hands[hand_idx].smallest_value() > 21:
            player.hands[hand_idx]=0
    player.hands=filter(None,hands)

相关问题 更多 >