如何以pythonic方式比较变量组合

时间:2018-04-14 01:52:42

标签: python list

我正在将一些文本数据从一个数据库迁移到一个新数据库,我必须验证这些记录是否有效。

我有以下变量:first_namecomplete_name

由于我有文本数据,我正在使用一些相似性函数。条件是:

def similar(first_name_1,first_name_2,complete_name_1,complete_name_2):
    temp_treshold  = 0

    temp_treshold = similarity_func(first_name_1,first_name_2)
    if  temp_treshold > threshold:
        return temp_treshold

    temp_treshold = similarity_func(first_name_1,complete_name_2)
    if  temp_treshold > threshold:
        return temp_treshold

    temp_treshold = similarity_func(complete_name_1,complete_name_2)
    if  temp_treshold > threshold:
        return temp_treshold

    temp_treshold = similarity_func(complete_name_1,complete_name_1)
    if  temp_treshold > threshold:
        return temp_treshold

如何以更清洁的方式进行比较?

2 个答案:

答案 0 :(得分:2)

将您的匹配项放入要发送到例程的参数列表中。 使用any功能检查所有功能,直到" good"找到一个。

pairs = [
    (first_name_1,first_name_2),
    (first_name_1,complete_name_2),
    (complete_name_1,complete_name_2),
    (complete_name_1,complete_name_1)
]

return any(similarity_func(name1, name2) > threshold
               for name1, name2 in pairs)

返回一个布尔值。如果你真的想要整数,那么在返回之前将结果转换为int

更改后更新

好;相反,您想要返回超过阈值的第一个相似度值。更新的代码 - 而不是单语句布尔值,使用:

for name1, name2 in pairs:
    sim = similarity_func(name1, name2)
    if sim > threshold:
       return sim

答案 1 :(得分:1)

只进行了四次比较,看似随意的比较,你所写的方式(至少对于原始版本 - 见下面的编辑版本)可能是最清晰,最恐怖的解决方案。当它没有违反DRY(不要重复自己)时,明确是好的。

但是,如果你有一个值列表,并希望将每个值与其他值的列表进行比较,并按照一些有意义的顺序进行比较,那么它绝对值得抽象。例如:

lefts = [first_name_1, last_name_1, complete_name_1]
rights = [first_name_2, last_name_2, complete_name_2]

如果您想以明显的顺序将每个lefts成员与每个rights成员进行比较,请复制并粘贴9次,并希望您没有错误或出现任何错误会是一个坏主意。所以你想要做这样的事情:

for left in lefts:
    for right in rights:
        if similarity_func(left, right) > threshold:
            return 1
return 0

或等同地:

for left, right in itertools.product(lefts, rights):
    if similarity_func(left, right) > threshold:
         return 1
return 0

或者:

if any(similarity_func(left, right) > threshold
       for left, right in itertools.product(lefts, rights)):
    return 1
return 0

由于您一直在改变您的问题...其中一些具有很好的优势,您可以轻松地更改它们以返回不同的内容。例如:

for left, right in itertools.product(lefts, rights):
    similarity = similarity_func(left, right)
    if similarity > threshold:
         return similarity
return 0

你的编辑也意味着你 现在重复了很多,因此,即使你有任意顺序的小型任意比较,我仍然会抽象它。我们可以使用zip超过两个有序序列(根据需要使用重复)而不是product,并且不需要更改其他内容:

lefts = (first_name_1, first_name_1, complete_name_1, complete_name_1)
rights = (first_name_2, complete_name_2, complete_name_2, complete_name_1)
for left, right in zip(lefts, rights):
    similarity = similarity_func(left, right)
    if similarity > threshold:
         return similarity
return 0