1

使用以下代码,我试图将所有卡片从套牌附加到字典中具有“酷”键的手上。

但由于某种原因,它只吸引了 3 次攻击中的 2 次。有人可以向我解释发生了什么吗?

attack = {"Name":"Attack","Cool":True}
defend = {"Name":"Defend"}

deck = [attack,attack,defend,defend,defend,attack]

hand = []

for card in deck:
    try:
        if card["Cool"] == True:
            hand.append(deck.pop(deck.index(card)))
    except Exception as e:
        print (e)

print(hand)
#this Print will show that it has only appended 2 of the 3 attack dictionaries.

我也用一个while循环试过这个,认为我把索引逻辑搞砸了,但无济于事:

编辑:多亏了@Chrispresso,我才能够思考如何使 while 循环工作!我已经在代码中编辑了那部分

i = 0
while i < len(deck):
    try:
        if deck[i]["Cool"] == True:
            hand.append(deck.pop(i))
            i += 1 #commenting out this line does the trick as you should not be increasing the index when you are popping something from the list as this basically makes you jump two places instead of one.
    except Exception as e:
        i += 1
        print (e)

非常感谢您提前提供的帮助!编辑:所以所需的输出将是

print(hand)
#[{"Name":"Attack","Cool":True},{"Name":"Attack","Cool":True},{"Name":"Attack","Cool":True}]

但目前的输出是:

print(hand)
#[{"Name":"Attack","Cool":True},{"Name":"Attack","Cool":True}]
4

4 回答 4

1

问题是你正在迭代你正在改变的东西。在这种情况下避免它的一种方法是简单地制作一个副本并对其进行迭代:

attack = {"Name":"Attack","Cool":True}
defend = {"Name":"Defend"}

deck = [attack,attack,defend,defend,defend,attack]

hand = []

for card in deck[:]:  # ITERATE OVER A COPY.
    try:
        if card["Cool"] == True:
            hand.append(deck.pop(deck.index(card)))
    except Exception as e:
        print (e)

# This will now show that hand has all 3 attack dictionaries.
print(hand)  
# And this shows they were removed from the deck.
print(deck)  # [{'Name': 'Defend'}, {'Name': 'Defend'}, {'Name': 'Defend'}]
于 2021-08-29T23:46:24.480 回答
0

正如@ggorlen 和@Chrispresso 的评论所提到的,您不应该在以这种方式迭代集合时改变集合。

attack = {"Name":"Attack","Cool":True}
defend = {"Name":"Defend"}

deck = [attack,attack,defend,defend,defend,attack]

    hand = []
    indexes_to_remove = []
    for card in deck:
       try:
           if card["Cool"] == True:            ​
               ​indexes_to_remove.append(deck.index(card))
               ​hand.append(card)
       ​except Exception as e:
           ​print (e)
    for deck_index in indexes_to_remove:
       try:
           deck.pop(deck_index) 
       ​except Exception as e:
           ​print (e)
于 2021-08-29T23:49:27.320 回答
0

不要使用索引语法([]),而是使用dict.get(key)函数。这确保 aKeyError不会被抛出(并且None在找不到密钥时默认返回):

然后这可以通过一个简单的列表过滤器来实现:

attack = {"Name":"Attack","Cool":True}
defend = {"Name":"Defend"}

deck = [attack,attack,defend,defend,defend,attack]
hand = [card for card in deck if card.get("Cool")] 
于 2021-08-29T23:51:16.487 回答
0

尝试以下操作:

attack = {"Name":"Attack","Cool":True}
defend = {"Name":"Defend"}

deck = [attack,attack,defend,defend,defend,attack]

hand = []

for i in range(len(deck)-1, -1, -1):
    try:
        if deck[i]["Cool"] == True:
            hand.append(deck[i])
            deck.pop(i)
    except Exception as e:
        print (e)
hand=hand[::-1]

输出:

>>>print(hand)
[{'Name': 'Attack', 'Cool': True}, {'Name': 'Attack', 'Cool': True}, {'Name': 'Attack', 'Cool': True}]
>>>print(deck)
[{'Name': 'Defend'}, {'Name': 'Defend'}, {'Name': 'Defend'}]
于 2021-08-29T23:41:51.173 回答