列表中更有效的字符串比较

More efficient string comparison in list

我正在编写一个程序来检测来自不同来源的大量文本中引用的法庭案例,并计算每个案例在文本中被引用的次数。问题源于这样一个事实,即案例在大多数文档中以两种状态存在:它们在给定文本中被完整引用一次或两次(即 "Timothy Ivory Carpenter v. United States of America"),然后在其余部分以较短的形式引用文档(即 "Carpenter v. U.S.")。目前,我正在将标题附加到一个庞大的列表中,然后 运行 通过 FuzzyWuzzy 字符串相似性检测包对列表进行调整。

现在我每次都将每个变量与其他变量进行比较,这是非常低效的。我的问题是:有没有办法只 运行 尚未执行的比较?我知道我可以将列表减半并使其更有效,但我仍然会将列表的 1/2 与自身进行比较。我的另一个想法是创建一个列表,其中已经过比较并交叉引用每一对,它是镜像版本(即“1:5”和“5:1”),就处理时间而言,最终为 34%比暴力破解要慢。

if variable_list = ['1','2','3','4','5']

我现在正在做的是比较以下各项:

1:1 1:2 1:3 1:4 1:5
2:1 2:2 2:3 2:4 2:5
3:1 3:2 3:3 3:4 3:5
4:1 4:2 4:3 4:4 4:5
5:1 5:2 5:3 5:4 5:5

这很糟糕,我知道

有没有办法让 python 改为 运行?

问题的一部分是你不能只检查 如果比较是 运行 因为重叠 检查是镜像的,不相同的(即冗余 3:1是已经比较过1:3,不是3:1)

我不需要自我参考,但我包括了 因为我认为这将基于 检查比较是否已经完成。

1:1 1:2 1:3 1:4 1:5
2:2 2:3 2:4 2:5
3:3 3:4 3:5
4:4 4:5
5:5

代码:

for var_1 in variable_list:

    for var_2 in variable_list:

    ### The chunk below sets the parameters to filter the strings

        if fuzz.token_set_ratio(var_2_reg_filt, var_1_reg_filt) > 91:

            if fuzz.ratio(var_2_reg_filt, var_1_reg_filt) > 87:

                if fuzz.partial_ratio(var_2_reg_filt, var_1_reg_filt) > 87:

                    if fuzz.token_sort_ratio(var_2_reg_filt, var_1_reg_filt) > 83:

                        ### This code then removes the longer of the two strings
                        ### -- and replaces it with the shorter version

                        if (len(var_1_reg_filt)) > (len(var_2_reg_filt)):

                            <<< Code to Replace var_1 with var_2 >>>

                        if (len(var_1_reg_filt)) < (len(var_2_reg_filt)):

                            <<< Code to Replace var_1 with var_2 >>>

这不是 "error" 代码问题,而是概念性问题。我包含了代码来展示我在做什么:运行 var_1 的每次迭代:var_2 通过三个不同的过滤器来剔除接近但不正确的匹配项。

我假设您想要变量的组合,请参阅 itertools 包中的 combinations 迭代器

import itertools
vars = ['1','2','3','4','5']
list(itertools.combinations(vars,2))
>>>
[('1', '2'),
 ('1', '3'),
 ('1', '4'),
 ('1', '5'),
 ('2', '3'),
 ('2', '4'),
 ('2', '5'),
 ('3', '4'),
 ('3', '5'),
 ('4', '5')]

如果您需要将它们与它们自己进行比较,您可以使用 combinations_with_replacement

所以最后你的循环应该看起来像

for var_1, var_2 in itertools.combinations(variable_list,2):
    ....