我正在尝试比较两个字符串并将其中一个字符串添加到列表中,如果它们几乎相等(由单个字母区分)。什么是最快的方法,因为我的单词超过90k并且这样做通常需要太长时间?
编辑:其中一个词(下面代码中的comparison_word)不会改变。
EDIT2:单词长度必须相等
这是我目前的代码:
for word in set_of_words:
amount = 0
if len(word) == len(comparison_word):
for i in range(len(word)):
if comparison_word[i] != word[i]:
amount += 1
if amount == 1:
list_of_words.append(word)
return list_of_words
答案 0 :(得分:2)
您可能会发现zip比索引更有效:
def almost_equal(set_of_words,comp):
ln = len(comp)
for word in set_of_words:
count = 0
if len(word) == ln:
for a, b in zip(word, comp):
count += a != b
if count == 2:
break
else:
yield word
演示:
In [5]: list(almost_equal(["foo","bar","foob","foe"],"foa"))
Out[5]: ['foo', 'foe']
答案 1 :(得分:1)
我们的想法是减少正在完成的工作量:
n_comparison_word = len(comparison_word)
for word in set_of_words:
amount = 0
n_word = len(word)
if n_word != n_comparison_word:
continue
for i in range(n_word):
if comparison_word[i] != word[i]:
amount += 1
if amount == 2:
break
if amount == 1:
list_of_words.append(word)
return list_of_words
一些注意事项:
len(comparison_word)
的值只需计算一次(永远)。len(word)
的值需要计算一次(每次迭代循环)。amount
达到值2时,您可以停止查看单词(或更多 - 在任何情况下,该单词都不能再成为结果的一部分。)关于代码中使用的continue
和break
语句,可能值得阅读this part of the Python documentation。
答案 2 :(得分:1)
以下在约25毫秒内搜索我的61K字词典。
import re
def search(word, text):
ws = [r'\b{}[^{}]{}\b'.format(w[:i],w[i],w[i+1:]) for i in range(len(word))]
for mo in re.finditer('|'.join(ws), text):
yield mo.group()
with open("/12dicts/5desk.txt") as f:
text = f.read()
for hit in search('zealoos', text):
print(hit) #prints zealous
假设字符串列表在一个文件中,每行一个字符串,将其作为一个长字符串读取,并使用正则表达式在字符串中搜索匹配项。
search()
会说“'什么'并把它变成这样的正则表达式:
\b[^w]hat\b|\bw[^h]at\b|\bwh[^a]t\b|\bwha[^t]\b
然后扫描所有单词并找到所有近乎未命中 - 以C-speed。
答案 3 :(得分:0)
Haven没有进行详尽的测试,但如果comparison_word
不是太长(少于6个字母),并且您的set_of_words
可以更改,那么计算所有可接受的内容可能是值得的单词,将它们存储在一个集合中,只需遍历set_of_words
并测试word in acceptable_words
。
如果没有,请点击我的代码:
for word in set_of_words:
different_letter_exists = False
length = len(word)
if length == len(comparison_word):
for i, letter in enumerate(word):
if letter != comparison_word[i]:
if different_letter_exists:
break
else:
different_letter_exists = True
if i == length:
list_of_words.append(word)
基本上:对于每个单词,一旦遇到不同的字母,different_letter_exists
将设置为True。如果你再次遇到它,你就会脱离循环。只有i == length
才会添加一个新单词,只有当enumerate
一直到达结尾时才会发生这种情况,只有当只有一个不同的字母存在时才会发生。