在谈到我的this问题时,我意识到语料库太大了,在进行levenshtein计算之前,需要将其分成多个小列表。下面的代码是我的简单尝试,但我想知道是否有一种更优雅的方法:
import csv#, StringIO
import itertools, Levenshtein
# open the newline-separated list of words
path = '/Users/path/'
file = path + 'wordlist.txt'
output1 = path + 'ortho1.csv'
output2 = path + 'ortho2.csv'
output3 = path + 'ortho3.csv'
output4 = path + 'ortho4.csv'
output5 = path + 'ortho5.csv'
output6 = path + 'ortho6.csv'
words = sorted(set(s.strip() for s in open(file)))
# words is a list with 16349, so I split it in to 6 mini lists
verbs1 = words[:3269]
verbs2 = words[3269:13080]
verbs3 = words[13081:9811]
verbs4 = words[9812:6542]
verbs5 = words[6543:3273]
verbs6 = words[3274:len(words)]
对于上面的每个列表,我计算以下循环:
with open(output1, 'wb') as f:
writer = csv.writer(f, delimiter=",", lineterminator="\n")
for a, b in itertools.product(verbs1, words):
if (a < b and Levenshtein.distance(a,b) <= 5):
writer.writerow([a, b, Levenshtein.distance(a,b)])
同样,一切都正常,但我想知道有没有一种更优雅的方法为每个迷你列表编写一个循环。你知道吗
把动词列在一个列表中:
然后使用该列表的长度创建一个长度相同的循环。通过使用索引,我们可以创建路径并访问谓词中的正确元素。你知道吗
您的代码存在一些问题,您还可以改进以下几点:
verbs
和output
各有六个不同的变量,而是使用两个列表;这样可以更容易地调整“拆分点”或子列表的数量,并且不必复制粘贴代码块来比较六次单词;只需使用另一个循环即可words[13081:9811]
是空的,并且第二个索引小于第一个索引的任何其他索引也是空的verbs1 = words[:3269]
和verbs2 = words[3269:13080]
,words[3269]
将位于子列表的或中,因为第二个索引是独占的;以下列表也是如此a*x + b*x + c*x
与(a+b+c) * x
相同a < b
并取消product
的一半,不如改用^{<= 5
的对感兴趣,可以先进行一些其他检查,例如比较两个单词的长度,或设置包含字符的差异;这两种检查都比实际的编辑距离检查快,即O(n²),并且可能排除许多组合结合以上内容,您可以尝试以下方法(未经测试):
这里,
chunks
是split an iterator into chunks的函数,might_be_close
是比较例如长度或所包含字母集的辅助函数,如上所述。output
文件的大小可能仍然不同,但永远不会超过max_count
。你知道吗或者尝试这样做,以获得具有确切
max_count
项的输出文件:这里,
filter_matches
生成器对组合进行预过滤,我们将它们分块到正确的大小。你知道吗相关问题 更多 >
编程相关推荐