对Python for循环行为和if语句感到困惑

2024-04-24 13:19:09 发布

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

我希望有人能向我解释这种行为以及发生了什么。你知道吗

如果我运行以下代码:

phrase = "Don't Panic!"
phraseList = list(phrase)
print(phrase)
print(phraseList)

ontap = ['o', 'n', 't', 'a', 'p']

for letter in phraseList:
    print("Letter ", letter)
    #if letter not in ontap:
    #    phraseList.remove(letter)

print(phraseList)

我得到以下预期输出:

Don't Panic!
['D', 'o', 'n', "'", 't', ' ', 'P', 'a', 'n', 'i', 'c', '!']
Letter  D
Letter  o
Letter  n
Letter  '
Letter  t
Letter   
Letter  P
Letter  a
Letter  n
Letter  i
Letter  c
Letter  !
['D', 'o', 'n', "'", 't', ' ', 'P', 'a', 'n', 'i', 'c', '!']

但是,如果我删除这些评论,我会得到这种意想不到的行为:

Don't Panic!
['D', 'o', 'n', "'", 't', ' ', 'P', 'a', 'n', 'i', 'c', '!']
Letter  D
Letter  n
Letter  '
Letter   
Letter  a
Letter  n
Letter  i
Letter  !
['o', 'n', 't', 'P', 'a', 'n', 'c']

所以我的问题是,在循环中,我希望在列表之前首先执行PRINTremove函数运行,但它似乎不是这样工作的。为什么?它似乎跳过了印刷品上的字母,比如字母C。 还有为什么compare似乎忽略了字母C,而它显然不在ontap变量中。你知道吗

我可能遗漏了一些非常明显的东西。它是否与调整列表大小并同时对其运行循环有关?你知道吗

谢谢你的真知灼见。你知道吗


Tags: 代码in列表for字母removelistprint
1条回答
网友
1楼 · 发布于 2024-04-24 13:19:09

正如对问题的评论所证实的那样,问题确实是在迭代时修改phraseList。更详细地说,发生的事情是这样的:当您进入for循环时,会创建一个迭代器来迭代phraseList。在第一次迭代中,迭代器提供phraseList[0],即D。这不在ontap列表中,所以我们要phraseList.remove('D')。在下一次迭代中,phraseList现在是['o', 'n', "'", 't', ...],但是迭代器不知道它被更改了-它只知道现在它需要提供phraseList[1],现在是n。这就是为什么第二次迭代打印n,而不是oc永远不会从phraseList中删除,因为它只出现在i第一次出现之后。当iphraseList中删除时,在下一个循环中,c被跳过。(类似地,P不会被删除,因为它正好位于<space>的第一个实例之后。)

修复循环的最简单方法是迭代phraseList的副本:

for letter in list(phraseList):
    print("Letter ", letter)
    if letter not in ontap:
        phraseList.remove(letter)

这样更改原始的phraseList不会影响迭代。你也可以更简洁(而且,在我看来,更清楚)的列表理解。以下内容正好完成了上面for循环的功能:

phraseList = [letter for letter in phraseList if letter in ontap]

相关问题 更多 >