Python和Palindromes
-
10-10-2019 - |
题
我最近写了一种循环的方法 /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
解决方案
wordlist = wl.readlines()
当您执行此操作时,最后有一个新的行字符,因此您的列表就像:
['eye\n','bye\n', 'cyc\n']
其元素显然不是回文。
你需要这个:
['eye','bye', 'cyc']
所以 strip
Newline字符,应该很好。
一行这样做:
wordlist = [line.strip() for line in open('/usr/share/dict/words')]
编辑:在列表上迭代并修改它会导致问题。使用列表理解,如 马修.
其他提示
其他人已经指出了更好的解决方案。我想向您展示为什么列表在运行代码后没有空。自从你 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
等等。
因此,您的代码删除了一半的条目。道德:在您迭代时,切勿修改列表(除非您确切地知道自己在做什么:))。
我认为有两个问题。
首先,将所有单词读入列表的重点是什么?为什么不依次处理每个单词,如果它是回文,请打印它。
其次,提防白道。您在每个末尾都有新线 word
s!
由于您没有识别任何allindromes(由于空格),因此您将尝试从列表中删除每个项目。当您迭代时!
该解决方案在一秒钟以下运行良好,并确定了许多回文:
for word in open('/usr/share/dict/words', 'r'):
word = word.strip()
if ispalindrome(word):
print word
编辑:
也许更多的“ Pythonic”是使用 发电机 表达式:
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)
它不会返回所有单词。它返回一半。这是因为您在迭代时修改列表,这是一个错误。一个更简单,更有效的解决方案是使用列表理解。您可以修改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)]
您在每个单词的末尾都包含newline /usr/share/dict/words
. 。这意味着您再也找不到任何回文。如果您只在发现壁画时,就可以加快速度,而不是从列表中删除非预选。