我最近写了一个方法来循环浏览/usr/share/dict/words
并使用我的ispalindrome(x)
方法返回回文列表
这里有一些代码......它有什么问题?它只会停顿10分钟,然后返回文件中所有单词的列表
def reverse(a): return a[::-1] def ispalindrome(a): b = reverse(a) if b.lower() == a.lower(): return True else: return False wl = open('/usr/share/dict/words', 'r') wordlist = wl.readlines() wl.close() for x in wordlist: if not ispalindrome(x): wordlist.remove(x) print wordlist
答案 0 :(得分:6)
wordlist = wl.readlines()
执行此操作时,最后会有一个换行符,因此您的列表如下:
['eye\n','bye\n', 'cyc\n']
其元素显然不是回文。
你需要这个:
['eye','bye', 'cyc']
所以strip
换行符,应该没问题。
要在一行中执行此操作:
wordlist = [line.strip() for line in open('/usr/share/dict/words')]
编辑:迭代列表并修改它会导致问题。使用列表理解,如Matthew所指出的那样。
答案 1 :(得分:3)
我认为有两个问题。
首先,将所有单词读入列表有什么意义?为什么不依次处理每个单词并在它是回文时打印出来。
其次,注意空白。您在每个word
s!
由于您没有识别任何回文(由于空白),您将尝试从列表中删除所有项目。当你在迭代它时!
这种解决方案在一秒钟内运行良好并识别出大量的回文:
for word in open('/usr/share/dict/words', 'r'):
word = word.strip()
if ispalindrome(word):
print word
修改:
也许更多'pythonic'是使用generator表达式:
def ispalindrome(a):
return a[::-1].lower() == a.lower()
words = (word.strip() for word in open('/usr/share/dict/words', 'r'))
palindromes = (word for word in words if ispalindrome(word))
print '\n'.join(palindromes)
答案 2 :(得分:3)
其他人已经指出了更好的解决方案。我想告诉你为什么在运行代码后列表不为空。由于其他答案中提到的“换行问题”,您的ispalindrome()
函数永远不会返回True
,因此您的代码会针对每个项目调用wordlist.remove(x)
。那么为什么列表最后不是空的呢?
因为您正在迭代它时修改列表。请考虑以下事项:
>>> l = [1,2,3,4,5,6]
>>> for i in l:
... l.remove(i)
...
>>> l
[2, 4, 6]
当您移除1
时,其余元素向上移动一步,因此现在l[0]
为2
。但迭代计数器已经提前,并将在下一次迭代中查看l[1]
,因此删除3
,依此类推。
所以你的代码删除了一半的条目。道德:在迭代时不要修改列表(除非你确切地知道你正在做什么:)。)。
答案 3 :(得分:2)
它不会返回所有单词。它返回一半。这是因为你在迭代它时修改列表,这是一个错误。一种更简单,更有效的解决方案是使用列表理解。你可以修改sukhbir来完成整个事情:
[word for word in (word.strip() for word in wl.readlines()) if ispalindrome(word)]
你也可以解决这个问题:
stripped = (word.strip() for word in wl.readlines())
wordlist = [word for word in stripped if ispalindrome(word)]
答案 4 :(得分:1)
您在/usr/share/dict/words
中的每个单词的末尾都包含换行符。这意味着你永远找不到任何回文。如果您只是在找到它们时记录回文,而不是从列表中删除非回文,你会加快速度。