python 和回文

发布于 2024-10-11 06:35:58 字数 482 浏览 4 评论 0原文

我最近编写了一个方法来循环遍历 /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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

怪我太投入 2024-10-18 06:35:58
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 所指出的。

wordlist = wl.readlines()

When you do this, there is a new line character at the end, so your list is like:

['eye\n','bye\n', 'cyc\n']

the elements of which are obviously not a palindrome.

You need this:

['eye','bye', 'cyc']

So strip the newline character and it should be fine.

To do this in one line:

wordlist = [line.strip() for line in open('/usr/share/dict/words')]

EDIT: Iterating over a list and modifying it is causing problems. Use a list comprehension,as pointed out by Matthew.

淤浪 2024-10-18 06:35:58

其他人已经指出了更好的解决方案。我想向您展示为什么运行代码后列表不为空。由于其他答案中提到的“换行符问题”,您的 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 等等。

所以你的代码删除了一半的条目。寓意:在迭代列表时切勿修改列表(除非您确切知道自己在做什么:))。

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 return True because of the "newlines problem" mentioned in the other answers, your code will call wordlist.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:

>>> l = [1,2,3,4,5,6]
>>> for i in l:
...     l.remove(i)
...
>>> l
[2, 4, 6]

When you remove the 1, the rest of the elements travels one step upwards, so now l[0] is 2. The iteration counter has advanced, though, and will look at l[1] in the next iteration and therefore remove 3 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 :)).

悲凉≈ 2024-10-18 06:35:58

我认为有两个问题。

首先,将所有单词读入列表有什么意义?如果它是回文,为什么不依次处理每个单词并打印它呢?

其次,要注意空格。每个单词的末尾都有换行符!

由于您没有识别任何回文(由于空格),因此您将尝试从列表中删除每个项目。当你迭代它时!

该解决方案运行时间不到一秒,并识别出大量回文:

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)

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 words!

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:

for word in open('/usr/share/dict/words', 'r'):
    word = word.strip()
    if ispalindrome(word):
        print word

Edit:

Perhaps more 'pythonic' is to use generator expressions:

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)
相思碎 2024-10-18 06:35:58

它不会返回所有单词。它返回一半。这是因为您在迭代列表时修改了列表,这是一个错误。一个更简单、更有效的解决方案是使用列表理解。您可以修改 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)]

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:

[word for word in (word.strip() for word in wl.readlines()) if ispalindrome(word)]

You can also break this up:

stripped = (word.strip() for word in wl.readlines())
wordlist = [word for word in stripped if ispalindrome(word)]
时光礼记 2024-10-18 06:35:58

您在 /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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文