Python 为什么';';死后能活下来吗?
这段代码中发生了一些奇怪的事情:Python 为什么';';死后能活下来吗?,python,string,python-2.7,python-3.x,Python,String,Python 2.7,Python 3.x,这段代码中发生了一些奇怪的事情: fh = open('romeo.txt', 'r') lst = list() for line in fh: line = line.split() for word in line: lst.append(word) for word in lst: numberofwords = lst.count(word) if numberofwords > 1: lst.remove(wo
fh = open('romeo.txt', 'r')
lst = list()
for line in fh:
line = line.split()
for word in line:
lst.append(word)
for word in lst:
numberofwords = lst.count(word)
if numberofwords > 1:
lst.remove(word)
lst.sort()
print len(lst)
print lst
romeo.txt取自
结果:
27
['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft', 'sun', 'the', 'the', 'through', 'what', 'window', 'with', 'yonder']
正如你所看到的,有两个“the”。为什么呢?我可以再次运行这部分代码:
for word in lst:
numberofwords = lst.count(word)
if numberofwords > 1:
lst.remove(word)
在第二次运行此代码后,它会删除剩余的“the”,但为什么第一次不起作用呢
正确输出:
26
['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft', 'sun', 'the', 'through', 'what', 'window', 'with', 'yonder']
在此循环中:
for word in lst:
numberofwords = lst.count(word)
if numberofwords > 1:
lst.remove(word)
lst
在迭代时被修改。不要那样做。一个简单的修复方法是迭代它的副本:
for word in lst[:]:
Python提供了美味的工具,使这类任务变得非常简单。通过使用内置功能,通常可以避免显式循环和就地修改循环变量时出现的问题:
with open('romeo.txt', 'r') as fh:
words = sorted(set(fh.read().replace('\n', ' ').split(' ')))
print(len(words))
print(words)
Dunno没有编辑它的原因您现在需要滚动查看结果我猜是在
.remove()
之后,for
循环没有正确循环(因为它可能无法再正确索引元素)。在迭代时修改列表可能会导致未定义的行为。@PeterWood因为Python没有C/C++意义上的“未定义行为”,所以最好说“在迭代时修改列表可能会导致奇怪的结果”。实际发生的事情是完全定义和确定的-列表迭代通过推进一个内部索引来工作,并且在当前索引之前删除一个元素会导致所有内容向左移动一个索引,因此您最终有效地跳过了下一个索引中的值(因为它现在在当前索引中)。它工作正常。我仍然不知道到底发生了什么,但感谢您的快速响应。@gunn我记得现在在迭代列表时不要修改它。当你了解更多信息时,它背后的原因可能会变得很清楚。是的@Ivc已经在下面的评论中澄清了这一点。我的问题对于word in reversed(lst):
将避免创建新列表这将是一个很好的答案,如果它解释了为什么你不应该修改正在迭代的列表。感谢分享代码!我对python还是新手,所以即使是最基本的方法我也很熟悉,但很高兴看到你能对简单的代码进行多大的改进。作为一个初学者没什么错!请注意,阅读上面代码中发生的事情是多么容易.read()
将文件内容转换为一段文本.replace()
将换行符更改为空格.split()
将所有内容分解为单词(空格)set()
将单词列表剔除为唯一的sorted()
对集合进行排序并返回一个列表(已排序)。希望有帮助。