Python 中 for..in 循环的意外输出
Unexpected output of for.. in loop in Python
我想 运行 一个 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)
下面的代码returns这样输出-
['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" 和 "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
那么,当完整代码为 运行 时,为什么不会发生这种情况?
您在迭代列表时正在编辑列表。因此,大小会在中途发生变化,最终会出现奇怪的行为。您可以改为创建一个新列表来保存过滤后的字符。
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])
其他答案和评论 100% 正确 - 切勿在遍历列表时修改它!可能有助于解决这类问题的是逆向思考问题:不是从列表中 删除 ,而是反转条件和 添加 到一个新列表。通过这种方式,它基于输入而不是改变输入来构建新的输出 = 更少的副作用、更清晰的代码、函数式编程原则等。@coldspeed 的列表理解是一种优雅的解决方案。
对原始代码进行最少更改的替代解决方案:
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 的代码现在几乎与此完全相同——我最初提交时不是这样。)
我想 运行 一个 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)
下面的代码returns这样输出-
['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" 和 "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
那么,当完整代码为 运行 时,为什么不会发生这种情况?
您在迭代列表时正在编辑列表。因此,大小会在中途发生变化,最终会出现奇怪的行为。您可以改为创建一个新列表来保存过滤后的字符。
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])
其他答案和评论 100% 正确 - 切勿在遍历列表时修改它!可能有助于解决这类问题的是逆向思考问题:不是从列表中 删除 ,而是反转条件和 添加 到一个新列表。通过这种方式,它基于输入而不是改变输入来构建新的输出 = 更少的副作用、更清晰的代码、函数式编程原则等。@coldspeed 的列表理解是一种优雅的解决方案。
对原始代码进行最少更改的替代解决方案:
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 的代码现在几乎与此完全相同——我最初提交时不是这样。)