在python中实现Levenshtein距离

时间:2010-11-13 16:45:55

标签: python levenshtein-distance

我已经实现了算法,但现在我想找到与其他字符串编辑距离最短的字符串的编辑距离。

以下是算法:

def lev(s1, s2):
    return min(lev(a[1:], b[1:])+(a[0] != b[0]), lev(a[1:], b)+1, lev(a, b[1:])+1)

2 个答案:

答案 0 :(得分:5)

您的“实施”有几个缺陷:

(1)它应该以{{1​​}}开头,而不是def lev(a, b):。请先了解(a)运行代码之前的好习惯(b)引用您实际运行的代码(通过复制/粘贴,而不是(容易出错)重新键入)。

(2)没有终止条件;对于任何参数,它最终会最终尝试评估def lev(s1, s2):,如果不是Python实现限制,它将永远循环:lev("", "")

您需要插入两行:

RuntimeError: maximum recursion depth exceeded

让它发挥作用。

(3)Levenshtein距离是递归定义的 。没有“这个”(唯一的)算法。递归代码在教室外很少见,然后只能以“稻草人”的身份出现。

(4)天真的实现需要时间和内存与if not a: return len(b) if not b: return len(a) 成比例...那些字符串通常不会比4到8长一点吗?

(5)你的天真实施更糟糕,因为它复制了输入片段。

你可以在网上找到工作非常天真的实现... google(“levenshtein python”)...寻找那些使用len(a) * len(b)额外内存的实现。< / p>

你要求的是什么(“与其他字符串编辑距离最短的字符串的编辑距离。”)没有意义......“字符串”??? “探戈需要两个人”: - )

您可能想要的(找到具有最小距离的集合中的所有字符串对),或者可能只是最小距离,这是一个简单的编程练习。你有什么尝试?

顺便说一句,通过简单算法找到这些对将需要执行O(max(len(a), len(b)))的O(N ** 2),其中N是集合中的字符串数...如果这是真实世界应用程序,您应该使用经过验证的代码而不是尝试自己编写代码。如果这是作业,你应该这样说。

答案 1 :(得分:0)

这就是你要找的东西吗?

import itertools
import collections

# My Simple implementation of Levenshtein distance
def levenshtein_distance(string1, string2):
    """
    >>> levenshtein_distance('AATZ', 'AAAZ')
    1
    >>> levenshtein_distance('AATZZZ', 'AAAZ')
    3
    """

    distance = 0

    if len(string1) < len(string2):
        string1, string2 = string2, string1

    for i, v in itertools.izip_longest(string1, string2, fillvalue='-'):
        if i != v:
            distance += 1
    return distance

# Find the string with the shortest edit distance.
list_of_string = ['AATC', 'TAGCGATC', 'ATCGAT']

strings_distances = collections.defaultdict(int)

for strings in itertools.combinations(list_of_string, 2):
    strings_distances[strings[0]] += levenshtein_distance(*strings)
    strings_distances[strings[1]] += levenshtein_distance(*strings)

shortest = min(strings_distances.iteritems(), key=lambda x: x[1])