我想通过编辑等于或小于一个数字的距离来生成名称的变体.我认为最简单的解决方案是递归.如果我将当前步骤的结果添加到递归之后,以下代码可以很好地工作;如果我在之前添加它们,则递归无法终止:

def generate_distance1(name):

    res = []
    
    # Deletion.
    for i in range(len(name)):
        if 0 == i:
            res.append(name[1:])
        elif len(name) - 1 == i:
            res.append(name[:-1])
        else:
            res.append(name[:i] + name[i+1:])

    # Substitution.
    for i in range(len(name)):
        if 0 == i:
            res.append("?" + name[1:])
        elif len(name) - 1 == i:
            res.append(name[:-1] + "?")
        else:
            res.append(name[:i] + "?" + name[i+1:])

    # Addition
    for i in range(len(name) + 1):
        if 0 == i:
            res.append("?" + name)
        elif len(name) == i:
            res.append(name + "?")
        else:
            res.append(name[:i] + "?" + name[i:])

    res = list(set(res))
    
    return res


def generate_distance(name, max_distance, before):
    if 0 == max_distance:
        return [name]

    dist1 = generate_distance1(name)
    if 1 == max_distance:
        return dist1

    if before:
        # This is not OK.
        res = dist1
    else:
        # This is OK.
        res = []

    for n in dist1:
        res.extend(generate_distance(n, max_distance - 1, before))

    if not before:
        res.extend(dist1)
        
    return list(set(res))

print(generate_distance("abracadabra", 2, before=False))

print(generate_distance("abracadabra", 2, before=True))

我使用的是Python3.11.6.我认为这个问题与词法作用域有关,可能还有闭包,但我不明白为什么;我也不能真正为这个问题制定一个更好的标题.为什么这个递归函数不能终止?

推荐答案

before版本的问题在于,for循环将扩展正在迭代的列表:

    for n in dist1:
        res.extend(generate_distance(n, max_distance - 1, before))

由于您已将res等同于dist1,因此上面的代码实际上是这样做的:

    for n in dist1:
        dist1.extend(generate_distance(n, max_distance - 1, before))

循环不应该迭代超过最初的dist1个条目,并且由于generate_distance将始终生成一个非空列表,所以这个循环永远不会结束(直到达到内存限制).

before方法的这个修正是为res创建一个新列表(就像您在after方法中也创建了一个新列表一样):

res = dist1[:]

与你的问题无关,但在generate_distance1分中,你不需要有if ... elif ... else个街区.您还可以将通用切片(在else种情况下)应用于前两种情况.删除、更新和插入 case 也是如此.

Python相关问答推荐

Polars LazyFrame在收集后未返回指定的模式顺序

如何将双框框列中的成对变成两个新列

沿着数组中的轴计算真实条目

使用索引列表列表对列进行切片并获取行方向的向量长度

通过Selenium从页面获取所有H2元素

聚合具有重复元素的Python字典列表,并添加具有重复元素数量的新键

如何获取TFIDF Transformer中的值?

log 1 p numpy的意外行为

删除字符串中第一次出现单词后的所有内容

在极性中创建条件累积和

多处理队列在与Forking http.server一起使用时随机跳过项目

如何在Python中使用另一个数据框更改列值(列表)

numpy.unique如何消除重复列?

Python Pandas—时间序列—时间戳缺失时间精确在00:00

从列表中获取n个元素,其中list [i][0]== value''

人口全部乱序 - Python—Matplotlib—映射

BeautifulSoup:超过24个字符(从a到z)的迭代失败:降低了首次深入了解数据集的复杂性:

如何在Python 3.9.6和MacOS Sonoma 14.3.1下安装Pyregion

Django Table—如果项目是唯一的,则单行

如何将ManyToManyfield用于Self类