python 和回文
我最近编写了一个方法来循环遍历 /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
i recently wrote a method to cycle through /usr/share/dict/words
and return a list of palindromes using my ispalindrome(x)
method
here's some of the code...what's wrong with it? it just stalls for 10 minutes and then returns a list of all the words in the file
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当你这样做时,末尾有一个新行字符,所以你的列表就像:
其中的元素显然不是回文。
你需要这个:
所以
strip
换行符应该没问题。要在一行中执行此操作:
编辑:迭代列表并修改它会导致问题。使用列表理解,正如 Matthew 所指出的。
When you do this, there is a new line character at the end, so your list is like:
the elements of which are obviously not a palindrome.
You need this:
So
strip
the newline character and it should be fine.To do this in one line:
EDIT: Iterating over a list and modifying it is causing problems. Use a list comprehension,as pointed out by Matthew.
其他人已经指出了更好的解决方案。我想向您展示为什么运行代码后列表不为空。由于其他答案中提到的“换行符问题”,您的 ispalindrome() 函数永远不会返回 True ,因此您的代码将调用 wordlist.remove(x) 对于每一个项目。那么为什么列表最后不为空呢?
因为您在迭代列表时正在修改列表。请考虑以下情况:
当您删除
1
时,其余元素向上移动一步,因此现在l[0]
为2
。不过,迭代计数器已经前进,并且将在下一次迭代中查看l[1]
,因此删除3
等等。所以你的代码删除了一半的条目。寓意:在迭代列表时切勿修改列表(除非您确切知道自己在做什么:))。
Others have already pointed out better solutions. I want to show you why the list is not empty after running your code. Since your
ispalindrome()
function will never returnTrue
because of the "newlines problem" mentioned in the other answers, your code will callwordlist.remove(x)
for every single item. So why is the list not empty at the end?Because you're modifying the list as you're iterating over it. Consider the following:
When you remove the
1
, the rest of the elements travels one step upwards, so nowl[0]
is2
. The iteration counter has advanced, though, and will look atl[1]
in the next iteration and therefore remove3
and so on.So your code removes half of the entries. Moral: Never modify a list while you're iterating over it (unless you know exactly what you're doing :)).
我认为有两个问题。
首先,将所有单词读入列表有什么意义?如果它是回文,为什么不依次处理每个单词并打印它呢?
其次,要注意空格。每个
单词
的末尾都有换行符!由于您没有识别任何回文(由于空格),因此您将尝试从列表中删除每个项目。当你迭代它时!
该解决方案运行时间不到一秒,并识别出大量回文:
编辑:
也许更“Pythonic”的是使用生成器 表达式:
I think there are two problems.
Firstly, what is the point in reading all of the words into a list? Why not process each word in turn and print it if it's a palindrome.
Secondly, watch out for whitespace. You have newlines at the end of each of your
word
s!Since you're not identifying any palindromes (due to the whitespace), you're going to attempt to remove every item from the list. While you're iterating over it!
This solution runs in well under a second and identifies lots of palindromes:
Edit:
Perhaps more 'pythonic' is to use generator expressions:
它不会返回所有单词。它返回一半。这是因为您在迭代列表时修改了列表,这是一个错误。一个更简单、更有效的解决方案是使用列表理解。您可以修改 sukhbir 来完成整个事情:
您也可以将其分解:
It doesn't return all the words. It returns half. This is because you're modifying the list while iterating over it, which is a mistake. A simpler, and more effective solution, is to use a list comprehension. You can modify sukhbir's to do the whole thing:
You can also break this up:
您在
/usr/share/dict/words
中的每个单词末尾添加换行符。这意味着你永远找不到任何回文。如果您只记录找到的回文,而不是从列表中删除非回文,您会加快速度。You're including the newline at the end of each word in
/usr/share/dict/words
. That means you never find any palindromes. You'll speed things up if you just log the palindromes as you find them, instead of deleting non-palindromes from the list, too.