我正在尝试创建一个名称匹配器,以比较说'JOHN LEWIS'
与'JOHN SMITH LEWIS'
。他们显然是同一个人,我想创建一个函数,当您输入这些名称时,它将变成一个列表,然后为您提供匹配的名称。
问题是我的循环返回'LEWIS'
与'LEWIS'
匹配,而'SMITH'
与'LEWIS'
匹配,这是因为它的顺序。
from pyjarowinkler import distance
entered_name = 'JOHN LEWIS'.split(' ') # equals ['JOHN','LEWIS']
system_name = 'JOHN SMITH LEWIS'.split(' ') # equals ['JOHN','SMITH','LEWIS']
ratio = []
for i in entered_name:
maximum = 0
for j in system_name:
score = distance.get_jaro_distance(i, j, winkler=True,
scaling=0.1)
while score > maximum:
maximum = score
new = (i, j, maximum)
system_name.remove(i)
#removes that name from the original list
ratio.append(new)
会返回如下内容:
[('JOHN', 'JOHN', 1.0), ('LEWIS', 'SMITH', 0.47)]
而不是:
[('JOHN', 'JOHN', 1.0), ('LEWIS', 'LEWIS', 1.0)]
另外,如果您尝试使用
'ALLY A ARM'
之类的'ALLY ARIANA ARMANI'
,如果您不执行'ALLY'
行,它会与remove(i)
匹配两次。这就是为什么我只想要独特的比赛!我只是不断收到错误或找不到的答案。
最佳答案
问题出在您的system_name.remove(i)
行上。首先,在遍历列表时修改列表通常是个坏主意。这可能导致意外行为。就您而言,这是您的代码正在执行的操作:
第一次通过,匹配'JOHN'
和'JOHN'
。没问题。
从'JOHN'
中删除system_name
。现在system_name = ['SMITH', 'LEWIS']
。
第二次通过i = 'LEWIS'
,j = 'SMITH'
,score = .47
大于0,因此您的支票score > maximum
通过
我们设置maximum = score
我们设置new = ('LEWIS', 'SMITH', 0.47)
我们从'LEWIS'
中删除system_name
。现在system_name = ['SMITH']
。呃哦
下面使用if
而不是while
循环进行简单重写,因为完全不需要while
循环:
for i in entered_name:
maximum = 0
for j in system_name:
score = distance.get_jaro_distance(i, j, winkler=True,
scaling=0.1)
if score > maximum:
maximum = score
new = (i, j, maximum)
system_name.remove(new[1]) # want to remove 'SMITH' in the example, not 'LEWIS'
ratio.append(new)
我所做的只是将
system_name.remove()
调用移到system_name
循环之外,并用i
替换j
(使用new[1]
,因为我不在j
循环之外)。