在文件中查找给定单词的字谜
Find anagrams of a given word in a file
好吧,对于 class,我们遇到了这个问题,我们需要能够输入一个单词,并从给定的文本文件 (wordlist.txt) 中使用该单词的任何字谜来制作一个列表在文件中找到单词。
到目前为止,我的代码如下所示:
def find_anagrams1(string):
"""Takes a string and returns a list of anagrams for that string from the wordlist.txt file.
string -> list"""
anagrams = []
file = open("wordlist.txt")
next = file.readline()
while next != "":
isit = is_anagram(string, next)
if isit is True:
anagrams.append(next)
next = file.readline()
file.close()
return anagrams
每次我尝试 运行 程序时,它只是 returns 一个空列表,尽管我知道存在字谜。有什么问题吗?
P.S。 is_anagram 函数如下所示:
def is_anagram(string1, string2):
"""Takes two strings and returns True if the strings are anagrams of each other.
list,list -> string"""
a = sorted(string1)
b = sorted(string2)
if a == b:
return True
else:
return False
我正在使用 Python 3.4
问题是您正在使用 readline
函数。来自文档:
file.readline = readline(...)
readline([size]) -> next line from the file, as a string.
Retain newline. A non-negative size argument limits the maximum
number of bytes to return (an incomplete line may be returned then).
Return an empty string at EOF.
这里的关键信息是"Retain newline"。这意味着如果您有一个包含单词列表的文件,每行一个单词,每个单词都将 return 与终端换行符一起编辑。所以当你打电话时:
next = file.readline()
你得到的不是 example
,你得到的是 example\n
,所以这永远不会匹配你的输入字符串。
一个简单的解决方案是在从文件中读取的行上调用 strip()
方法:
next = file.readline().strip()
while next != "":
isit = is_anagram(string, next)
if isit is True:
anagrams.append(next)
next = file.readline().strip()
file.close()
但是,这段代码有几个问题。首先,file
是一个糟糕的变量名称,因为这会掩盖 python file
模块。
与其重复调用 readline()
,不如利用打开的文件是一个生成文件行的迭代器这一事实:
words = open('wordlist.txt')
for word in words:
word = word.strip()
isit = is_anagram(string, word)
if isit:
anagrams.append(word)
words.close()
这里还要注意,由于 is_anagram
return 是对还是错,你
不需要将结果与 True
或 False
(例如 if isit
is True
)进行比较。您可以简单地单独使用 return 值。
哎呀,不要使用 for 循环:
import collections
def find_anagrams(x):
anagrams = [''.join(sorted(list(i))) for i in x]
anagrams_counts = [item for item, count in collections.Counter(anagrams).items() if count > 1]
return [i for i in x if ''.join(sorted(list(i))) in anagrams_counts]
这是另一个解决方案,我认为它非常优雅。这在 O(n * m) 中运行,其中 n 是单词数,m 是字母数(或 letters/word 的平均数)。
# anagarams.py
from collections import Counter
import urllib.request
def word_hash(word):
return frozenset(Counter(word).items())
def download_word_file():
url = 'https://raw.githubusercontent.com/first20hours/google-10000-english/master/google-10000-english-no-swears.txt'
urllib.request.urlretrieve(url, 'words.txt')
def read_word_file():
with open('words.txt') as f:
words = f.read().splitlines()
return words
if __name__ == "__main__":
# downloads a file to your working directory
download_word_file()
# reads file into memory
words = read_word_file()
d = {}
for word in words:
k = word_hash(word)
if k in d:
d[k].append(word)
else:
d[k] = [word]
# Prints the filtered results to only words with anagrams
print([x for x in d.values() if len(x) > 1])
好吧,对于 class,我们遇到了这个问题,我们需要能够输入一个单词,并从给定的文本文件 (wordlist.txt) 中使用该单词的任何字谜来制作一个列表在文件中找到单词。
到目前为止,我的代码如下所示:
def find_anagrams1(string):
"""Takes a string and returns a list of anagrams for that string from the wordlist.txt file.
string -> list"""
anagrams = []
file = open("wordlist.txt")
next = file.readline()
while next != "":
isit = is_anagram(string, next)
if isit is True:
anagrams.append(next)
next = file.readline()
file.close()
return anagrams
每次我尝试 运行 程序时,它只是 returns 一个空列表,尽管我知道存在字谜。有什么问题吗?
P.S。 is_anagram 函数如下所示:
def is_anagram(string1, string2):
"""Takes two strings and returns True if the strings are anagrams of each other.
list,list -> string"""
a = sorted(string1)
b = sorted(string2)
if a == b:
return True
else:
return False
我正在使用 Python 3.4
问题是您正在使用 readline
函数。来自文档:
file.readline = readline(...)
readline([size]) -> next line from the file, as a string.
Retain newline. A non-negative size argument limits the maximum
number of bytes to return (an incomplete line may be returned then).
Return an empty string at EOF.
这里的关键信息是"Retain newline"。这意味着如果您有一个包含单词列表的文件,每行一个单词,每个单词都将 return 与终端换行符一起编辑。所以当你打电话时:
next = file.readline()
你得到的不是 example
,你得到的是 example\n
,所以这永远不会匹配你的输入字符串。
一个简单的解决方案是在从文件中读取的行上调用 strip()
方法:
next = file.readline().strip()
while next != "":
isit = is_anagram(string, next)
if isit is True:
anagrams.append(next)
next = file.readline().strip()
file.close()
但是,这段代码有几个问题。首先,file
是一个糟糕的变量名称,因为这会掩盖 python file
模块。
与其重复调用 readline()
,不如利用打开的文件是一个生成文件行的迭代器这一事实:
words = open('wordlist.txt')
for word in words:
word = word.strip()
isit = is_anagram(string, word)
if isit:
anagrams.append(word)
words.close()
这里还要注意,由于 is_anagram
return 是对还是错,你
不需要将结果与 True
或 False
(例如 if isit
is True
)进行比较。您可以简单地单独使用 return 值。
哎呀,不要使用 for 循环:
import collections
def find_anagrams(x):
anagrams = [''.join(sorted(list(i))) for i in x]
anagrams_counts = [item for item, count in collections.Counter(anagrams).items() if count > 1]
return [i for i in x if ''.join(sorted(list(i))) in anagrams_counts]
这是另一个解决方案,我认为它非常优雅。这在 O(n * m) 中运行,其中 n 是单词数,m 是字母数(或 letters/word 的平均数)。
# anagarams.py
from collections import Counter
import urllib.request
def word_hash(word):
return frozenset(Counter(word).items())
def download_word_file():
url = 'https://raw.githubusercontent.com/first20hours/google-10000-english/master/google-10000-english-no-swears.txt'
urllib.request.urlretrieve(url, 'words.txt')
def read_word_file():
with open('words.txt') as f:
words = f.read().splitlines()
return words
if __name__ == "__main__":
# downloads a file to your working directory
download_word_file()
# reads file into memory
words = read_word_file()
d = {}
for word in words:
k = word_hash(word)
if k in d:
d[k].append(word)
else:
d[k] = [word]
# Prints the filtered results to only words with anagrams
print([x for x in d.values() if len(x) > 1])