【问题标题】:Python - Checking if all and only the letters in a list match those in a string?Python - 检查列表中的所有字母是否与字符串中的字母匹配?
【发布时间】:2017-01-08 04:28:25
【问题描述】:

我正在 Python 2.7 中创建一个 Anagram Solver

求解器获取用户输入的字谜,将每个字母转换为列表项,然后根据“.txt”文件的行检查列表项,将与字谜字母匹配的任何单词附加到possible_words 列表中,准备就绪用于打印。

它起作用了...几乎!


# Anagram_Solver.py

anagram = list(raw_input("Enter an Anagram: ").lower())

possible_words = []

with file('wordsEn.txt', 'r') as f:

    for line in f:

        if all(x in line + '\n' for x in anagram) and len(line) == len(anagram) + 1:

            line = line.strip()
            possible_words.append(line)

print "\n".join(possible_words)

对于没有重复字母的字谜,它可以正常工作,但对于诸如“hello”之类的单词,输出包含诸如“helio、whole、holes”等单词,因为求解器似乎不计算字母' L' 是 2 个单独的条目?

我做错了什么?我觉得我缺少一个简单的解决方案?

谢谢!

【问题讨论】:

  • 你的算法太简单了。与其检查anagram 中的每个字符是否都在line 中(这不足以识别字谜),不如检查两个字符串中每种字符的计数是否相同。
  • all(x in line + '\n' for x in anagram) 是问题所在。如果单词中有“l”,而 anagram 中有 100 个,它仍然会返回 True
  • 可能想看看stackoverflow.com/questions/39028548/… 的一些想法...(实际上是同一个问题)
  • @Ev.Kounis ,感谢您的提醒。我对 Python 还是很陌生,并认为我误解了 all() 函数的应用。我主要是蛮力强迫这条线直到我让它工作,我想没有完全理解它是如何工作的。如果它没有超出这个问题的范围,你能解释一下它的作用吗?
  • 获取字谜 (for x in anagram) 中存在的每个字母并检查它是否存在于行中 (x in line)。 all(x,y,z, ..)x and y and z and ... 相同,因此字谜中的所有字母也必须存在于该行中,但该行不能包含更多的 em (len(line) == len(anagram))。请以不同的方式处理换行符。它在那里没有任何地方XD

标签: python list python-2.7 pattern-matching anagram


【解决方案1】:

这可能是使用collections.Counter 最容易解决的问题

>>> from collections import Counter
>>> Counter('Hello') == Counter('loleH')
True
>>> Counter('Hello') == Counter('loleHl')
False

Counter 将检查字母和每个字母出现的次数是否相同。

【讨论】:

  • 或者只是sorted('Hello') == sorted('loleHl')作为这个答案:stackoverflow.com/questions/14990725/…
  • 感谢@mgilson 的回复,之前没听说过 Counter 类,但它看起来很有用!
  • 我选择了另一个正确的答案,因为它涉及的细节稍微多一点,我觉得这很有帮助,但是查看计数器模块的不同控制台输出很有用。还要感谢@Chris_Rands 的回复,似乎 sorted 方法的运行速度比使用集合快得多,所以我编辑了另一个答案以包含它。
【解决方案2】:

您的代码按预期运行。您实际上并没有检查一个字母是否出现两次(或 3 次以上),它只是检查了两次 if 'l' in word,对于至少有一个 l 的所有单词,这将始终为 True。

一种方法是计算每个单词的字母。如果字母数相等,则它是一个字谜。这可以通过collections.Counter 类轻松实现:

from collections import Counter
anagram = raw_input("Enter an Anagram: ").lower()

with file('wordsEn.txt', 'r') as f:
    for line in f:
        line = line.strip()
        if Counter(anagram) == Counter(line):
            possible_words.append(line)

print "\n".join(possible_words)

另一种方法是使用 sorted() 函数,正如 Chris 在另一个答案的 cmets 中所建议的那样。这会将 anagram 和 line 中的字母按字母顺序排序,然后检查它们是否匹配。此过程比集合方法运行得更快。

anagram = raw_input("Enter an Anagram: ").lower()

with file('wordsEn.txt', 'r') as f:
    for line in f:
        line = line.strip()
        if sorted(anagram) == sorted(line):
            possible_words.append(line)

print "\n".join(possible_words)

【讨论】:

  • 感谢您对我的代码的深入解释和重写。我已经从上面的评论中测试了 counter 方法和 Chris_Rands sorted 方法,发现 sorted 方法实际上处理速度明显更快,所以我将把它附加到这个答案中并标记为正确。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 2023-01-25
  • 2012-02-22
相关资源
最近更新 更多