我正在尝试创建一个名称匹配器来比较'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'
。没问题。 - 从
system_name
中删除'JOHN'
。现在system_name = ['SMITH', 'LEWIS']
。 - 第二次,
i = 'LEWIS'
、j = 'SMITH'
、score = .47
大于 0,所以你的检查分数>最大
通过了 - 我们设置
最大值 = 分数
- 我们设置
new = ('LEWIS', 'SMITH', 0.47)
- 我们从
system_name
中删除'LEWIS'
。现在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
循环之外)。
关于python - 如何在两个列表中找到紧密匹配的唯一元素? (这里使用距离函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56030798/