2012-04-20 55 views
0

我有一个带有单词列表的文件,我试图寻找逐行阅读的单词。 common_words文件的示例为:在python中读取文件时出现无限循环

yourself 
yourselves 
z 
zero 

该列表按字典顺序排序。

def isCommonWord(word): 

    commonWordList = open("common_words", 'r') 
    commonWord = commonWordList.readline() 
    commonWord = commonWord.rstrip("\n") 

    while commonWord <= word: 
     if commonWord == word: 
      return True 
     commonWord = commonWordList.readline() 
     commonWord = commonWord.rstrip("\n") 

    return False 

if isCommonWord("zeros"): 
    print "true" 
else: 
    print "false" 

现在这个函数进入一个无限循环。我不知道这是怎么发生的。任何帮助将不胜感激。 如果我尝试除“零”之外的其他变量,那么它工作得很好。只有“零”才会遇到麻烦。谢谢你的时间。

+0

你似乎继续readline'甚至达到文件结束后做'。 – jogojapan 2012-04-20 09:43:11

+0

你想用这个功能达到什么目的? – 2012-04-20 09:44:15

+0

@AshwiniChaudhary我有一个文件中的单词列表,我需要检查是否有任何给定的单词是在文件中的单词列表中。 – 2012-04-20 09:48:00

回答

1

for "yourself"<="zeros"条件为true,while循环将无限持续。

所以如果任何字都传递给那个大于其他字的函数,那么你的程序会运行到一个无限循环。例如 。对于"zz" “你自己”< =“zz”将进入无限循环,因为zzlexicographically大于文件common_words中的所有其他字。

一个更好的版本的isCommonword()将是:

def isCommonWord(word): 

    commonWordList = open("common_words.txt") 
    commonWord = [x.rstrip() for x in commonWordList] 
    if word in commonWord: 
     return True 
    else:return False 
+0

只需在commonWord 而不是 如果(真)返回字:返回true 否则:返回false – 2012-04-20 10:38:33

+0

我只是想坚持OP使用的格式。 – 2012-04-20 11:31:22

+0

你的代码没有问题,我的评论只是一个建议,使其不那么冗长(和imho更清晰) – 2012-04-20 12:17:36

2

readline将返回一个空字符串,当您试图读到文件的末尾,空字符串比较''任何话,那么你的循环条件始终为true,如果你正在寻找的字是>任何的文件中的单词。

common = set(ln.rstrip() for ln in open("common_words")) 
print("true" if "zeros" in common else "false") 
+0

但该函数适用于除“零”情况以外的所有情况。无论是列表中的单词而不是列表中的单词。 – 2012-04-20 09:46:38

+0

@QuaziFarhan:那是因为“零”比较文件中的任何单词。尝试用'zzz'进行更改,这也会进入无限循环。 – 2012-04-20 09:49:42

+0

它适用于不在列表中的单词,它们按字典顺序排列在最后一个单词之前。 – UmNyobe 2012-04-20 09:50:03

1

最可能的是:

这可以通过重写环路

def isCommonWord(word): 
    with open("common_words") as f: 
     for w in f: 
      w = w.rstrip() 
      if w == word: 
       return True 
      elif w > word: 
       break 

    return False 

虽然真正的解决问题的方法是读取文件一次,并建立一个set出它是固定的,"zeros"位于文件common_words中的所有单词后面,以便不存在匹配。当您敲击输入文件的EOF时,commonWord(与<fobj>.readline()一起阅读)将为空(""),并且空字符串(“永远返回”)小于“零”,因此您的循环条件永远不会终止。

切换到循环条件:

while commonWord and commonWord <= word: 
    ... 
0

你还没有添加为循环退出如果单词没有找到,是文件中的最后一个字后lexographically的方式。 “零”的文件中,而不是“零”

while循环的一个相当直接翻译,将工作可能是

for commonWord in commonWordList: 
    commonWord = commonWord.rstrip("\n") 
    if commonWord <= word: 
     break 
    elif commonWord == word: 
     return True 
return False 

for循环到达文件末尾时自动终止

+1

不完全 - 如果从文件中间缺少单词,则循环将终止。 – katrielalex 2012-04-20 09:47:57

3

问题在于zeros会在之后出现这是文件中的最后一个单词 - 但是您不检查这一点。而且,readline()只会给你一个空字符串,如果你已经到达文件的末尾,所以循环只是不断思考“还没有”,并且会一直持续下去。

顺便说一句,有这样做的更好的方法,使用列表排序的事实:看看二进制搜索

事实上,如果您有足够的内存空间,您可以做得更好:只需将整个文件读入一个大的set,然后就可以持续检查会员资格!

+0

该列表对于内存(理论上)来说可能非常大,所以我不能总是假定会有足够的内存,但当然如您所说,可以实现某种二进制搜索方式。我打算这样做,只是在最初阶段。 – 2012-04-20 10:02:57

+0

够公平的。 (您也可以使用像'shelve'举行大集。) – katrielalex 2012-04-20 11:45:02

0

问题可能出在您的条件commonWord <= word。尝试使用!=并检查readline是否正在返回某些内容。如果该单词在列表中,则返回true,如果它不是什么都是打破循环:)