2015-07-11 68 views
8

奇怪的事情发生在这个代码:为什么'。'在'.remove'后生存?

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从http://www.pythonlearn.com/code/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'] 

正如你可以看到,有两个 '的'。这是为什么?这段代码运行它删除其余“的”,但为何它没有工作的第一次第二次后

for word in lst: 
    numberofwords = lst.count(word) 
    if numberofwords > 1: 
     lst.remove(word) 

:我可以再次运行这部分代码?

正确的输出:

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'] 
+0

dunnno为什么它被编辑你现在需要滚动才能看到结果 – Gunnm

+2

我的猜测是在'.remove()'之后,'for'循环没有正确循环(因为它可能无法正确地对元素进行索引)。 –

+4

迭代时修改列表可能会导致未定义的行为。 –

回答

14

在该循环:

for word in lst: 
    numberofwords = lst.count(word) 
    if numberofwords > 1: 
     lst.remove(word) 

lst而遍历它被修改。不要这样做。一个简单的解决方法是迭代它的副本:

for word in lst[:]: 
+0

它的工作原理。我仍然不知道到底发生了什么,但感谢您的快速反应。 – Gunnm

+3

@Gunnm现在记住不要在修改列表的同时迭代它。当你了解更多时,它背后的原因可能变得清晰。 –

+0

是@Ivc已经在我的问题 – Gunnm

6

Python使得美味的工具可用于使这些类型的任务非常容易。通过使用什么是内置的,通常可以避开各种你与显式循环看到的问题和修改循环变量,就地:

with open('romeo.txt', 'r') as fh: 
    words = sorted(set(fh.read().replace('\n', ' ').split(' '))) 

print(len(words)) 
print(words) 
+0

感谢分享代码!我仍然对python很陌生,所以即使使用大多数基本方法,我仍然很困难,但很高兴看到您可以提高简单代码的质量。 – Gunnm

+1

成为初学者没有错!注意阅读上面代码中发生的事情是多么容易。 '。read()'将文件内容拼写成一个文本块。 '.replace()'将换行符更改为空格。 '.split()'把所有东西都分解成单词(空格)。 'set()'将单词列表筛选为唯一。 'sorted()'对集合进行排序并返回一个列表(有序)。希望有所帮助。 –

+0

是的。我非常喜欢学习python。 – Gunnm

相关问题