Python中for ... in循环的意外输出

时间:2017-06-12 05:50:10

标签: python list for-loop python-3.6

我想运行一个for循环来检查字符串中的每个字母,如果wanted列表中包含该字母,那么我希望该字母留下来,如果wanted不包含该字母,那么我想删除它。

phrase = "Don't panic"
pList = list(phrase)
print(pList)
wanted = ["o","n","t","a","p"]
for anything in pList:
    print("Now checking", anything)
    if anything not in wanted:
        print("Removed",anything) 
        pList.remove(anything)
    elif anything in wanted:
        print("Didn't remove", anything)

print(pList)

以下代码返回此输出 -

['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c']                                                   

Now checking D                                                                                       
Removed D                                                                                                                                                                                           
Now checking n                                                                                          
Didn't remove n                                                                                         
Now checking '                                                                                           
Removed '                                                                                                                                                                                               
Now checking                                                                                              
Removed                                                                                                                                                                                                 
Now checking a                                                                                           
Didn't remove a                                                                                         
Now checking n                                                                                           
Didn't remove n                                                                                           
Now checking i                                                                                          
Removed i                                                                                                                                                                                       
['o', 'n', 't', 'p', 'a', 'n', 'c']   

代码不会删除最后一个字母(即" c")和字母" o"," t"," p& #34;和" c"没有显示Now checking输出。

我尝试删除一些行并运行 -

phrase = "Don't panic"
pList = list(phrase)
print(pList)
wanted = ["o","n","t","a","p"]
for anything in pList:
    print("Now checking", anything)

这次输出很有意义 -

Now checking D                                                                                            
Now checking o                                                                                            
Now checking n                                                                                            
Now checking '                                                                                            
Now checking t                                                                                            
Now checking                                                                                              
Now checking p                                                                                            
Now checking a                                                                                            
Now checking n                                                                                            
Now checking i                                                                                            
Now checking c 

那么为什么在运行完整代码时不会发生这种情况呢?

2 个答案:

答案 0 :(得分:1)

您在迭代时编辑列表。因此,大小将在中途发生变化,最终会出现奇怪的行为。您可以创建一个新列表来保存已过滤的字符。

phrase = "Don't panic"
pList = list(phrase)
new_plist = []
wanted = ["o","n","t","a","p"]
for i, anything in enumerate(pList):
    print("Now checking", anything)
    if anything in wanted:
        print("Didn't remove", anything)
        new_plist.append(anything)
    else:
        print("Removed", anything)

print(new_plist)

使用列表推导的一种更简单的方法是

pList = ''.join([i for i in pList if i not in wanted])

答案 1 :(得分:1)

其他答案和评论100%正确 - 永远不要在迭代时修改列表!可能有助于解决这些问题的方法是反过来考虑问题:而不是从列表中删除,将条件反转并将添加添加到新列表中。这样它就可以根据输入建立一个新的输出,而不是改变输入=减少副作用,更清晰的代码,函数式编程原理等。@ coldspeed的list comprehension就是这种优雅的解决方案。

对原始代码进行最少更改的替代解决方案:

phrase = "Don't panic"
pList = list(phrase)
print(pList)
wanted = ["o","n","t","a","p"]
finalList = []
for anything in pList:
    print("Now checking", anything)
    if anything in wanted:
        finalList.append(anything)
        print("Didn't remove", anything)
    else:
        print("Removed",anything)

print(finalList)

现在pList未被修改,新的finalList包含所需的结果。 (编辑:实现@coldspeed的代码现在几乎与此完全相同 - 当我最初提交时不是这样。)