【发布时间】:2022-08-11 23:38:03
【问题描述】:
使用 python,我希望遍历包含数千个条目的列表。对于列表中的每个项目,它需要与其他列表中的项目(包含数万个条目)进行比较,并进行部分比较检查。一旦找到高于设定比例的匹配项,它将停止并移动到下一个项目。
一个挑战:我无法安装任何额外的 python 包来完成这项工作,并且仅限于 python 3.4.2 发行版。
下面是我正在使用的一些示例代码。如果列表很小,它工作得很好,但是一旦我将它应用于非常大的列表,运行时可能需要几个小时才能完成。
from difflib import SequenceMatcher
ref_list = [] #(contains 4k sorted entries - long complex strings)
list1 = [] #(contains 60k sorted entries - long complex strings)
list2 = [] #(contains 30k sorted entries - long complex strings)
all_lists = [list1,list2]
min_ratio = 0.93
partMatch = \'\'
for ref in ref_list:
for x in range(len(all_lists)):
for str1 in all_lists[x]:
check_ratio = SequenceMatcher(None, ref, str1).quick_ratio()
if check_ratio > min_ratio:
partMatch = str1 #do stuff with partMatch later
break
我在想对 all_lists[x] 进行二分搜索可以解决这个问题。如果我的计算是正确的,一个 60k 的列表只需要 16 次尝试就可以找到部分匹配。
但是,问题在于字符串的类型。一个典型的字符串长度可以是 80 到 500 个字符,例如
lorem/ipsum/dolor/sit/amet/consectetur/adipiscing/elit/sed/do/eiusmod/tempor/incididunt/ut/labore/et/dolore/magna/aliqua/Ut/enim/ad/minim/veniam/quis/nostrud/exercitation
尽管列表已排序,但我不确定如何验证中点。例如,如果我缩短字符串以使其更易于阅读并提供以下列表:
ref_list = [\'past/pre/dest[5]\']
list1 = [\'abc/def/ghi\',\'xry/dos/zanth\']
list2 = [\'a/bat/cat\', \'ortho/coli\', \'past/pre/dest[6]\', \'past/tar/lot\', \'rif/six/1\', \'tenta[17]\', \'ufra/cos/xx\']
我们可以看到ref_list 中字符串的部分匹配是list2[2]。但是,使用二分搜索,我如何确定部分匹配肯定在 list2 的前半部分?
我真的很感激这方面的任何帮助。考虑到我需要处理包含数万个条目的列表,效率是这里最重要的因素。
-
我不确定您所说的 SequenceMatcher 是什么不必要的噪音。提供的代码的第一行是
from difflib import SequenceMatcher。在我的用例中,SequenceMatcher 用于比较两个字符串并提供它们匹配程度的比率值。 0 表示没有匹配的字符,1 表示字符串相同。我已将最小比率设置为 0.93,找到的第一个满足此要求的字符串被识别为部分匹配。 -
对不起,我误读了那部分的问题。
-
我建议花更多时间创建一个最小的可重现示例,并具有明确的最小输入和输出。很难正确优化不清楚的东西。
-
我很确定您不能使用二进制搜索,因为输入没有根据您正在计算的部分匹配函数进行排序,例如
gbcd将与abcd和zbcd进行部分匹配,但任何以不同于a和z的单词开头的单词都将介于两者之间。
标签: python