Python 嵌套函数递归调用中的UnboundLocalError

Python 嵌套函数递归调用中的UnboundLocalError,python,recursion,nested-function,Python,Recursion,Nested Function,我有以下Python代码: def find_words(letters): results = set() def extend_prefix(w, letters): if w in WORDS: results.add(w) if w not in PREFIXES: return for L in letters: result = extend_prefix(w + L, letters.repl

我有以下Python代码:

def find_words(letters):
    results = set()

    def extend_prefix(w, letters):
        if w in WORDS: results.add(w)
        if w not in PREFIXES: return
        for L in letters:
            result = extend_prefix(w + L, letters.replace(L, "", 1))
            results = results | result

    extend_prefix('', letters)
    return results

print find_words("ABCDEFGH")
当我运行它时,会出现以下错误:

Traceback (most recent call last):
  File "ExtendPrefix.py", line 44, in <module>
    print find_words("ABCDEFGH")
  File "ExtendPrefix.py", line 41, in find_words
    extend_prefix('', letters)
  File "ExtendPrefix.py", line 38, in extend_prefix
    result = extend_prefix(w + L, letters.replace(L, "", 1))
  File "ExtendPrefix.py", line 38, in extend_prefix
    result = extend_prefix(w + L, letters.replace(L, "", 1))
  File "ExtendPrefix.py", line 35, in extend_prefix
    if w in WORDS: results.add(w)
UnboundLocalError: local variable 'results' referenced before assignment
回溯(最近一次呼叫最后一次):
文件“ExtendPrefix.py”,第44行,在
打印查找单词(“ABCDEFGH”)
文件“ExtendPrefix.py”,第41行,在find_words中
扩展前缀(“”,字母)
文件“ExtendPrefix.py”,第38行,扩展前缀
结果=扩展前缀(w+L,字母。替换(L,“,1))
文件“ExtendPrefix.py”,第38行,扩展前缀
结果=扩展前缀(w+L,字母。替换(L,“,1))
文件“ExtendPrefix.py”,第35行,扩展前缀
如果w大写:结果。添加(w)
UnboundLocalError:赋值前引用的局部变量“results”

它显然无法在扩展前缀的递归调用中找到结果。这是为什么?我如何修复它?

因为您在嵌套函数中分配结果,Python假定您使用的是一个局部作用域变量,并在第35行抛出,即使它是更高作用域中的有效名称。如果您只是读取变量而不是写入变量,那么它通常会在更高的命名空间对象上工作。但一旦出现赋值运算符,就跳转到本地名称空间

发件人:

Python的一个特殊怪癖是——如果没有全局语句在 效果–对名称的指定始终位于最内部的范围内。 赋值不复制数据-它们只是将名称绑定到对象

要解决此问题,最简单的方法是将要使用的变量传递到函数头中:

def extend_prefix(w, letters, results):
        if w in WORDS: results.add(w)
        if w not in PREFIXES: return
        for L in letters:
            extend_prefix(w + L, letters.replace(L, "", 1), results)

同样,您编写函数的方式是,您没有返回一个集合,因此
results=results | result
会爆炸,结果是非类型的。

因为您在嵌套函数中分配结果,Python假定您使用的是一个局部作用域变量,并在第35行抛出,即使它在更高的作用域中是一个有效名称。如果您只是读取变量而不是写入变量,那么它通常会在更高的命名空间对象上工作。但一旦出现赋值运算符,就跳转到本地名称空间

发件人:

Python的一个特殊怪癖是——如果没有全局语句在 效果–对名称的指定始终位于最内部的范围内。 赋值不复制数据-它们只是将名称绑定到对象

要解决此问题,最简单的方法是将要使用的变量传递到函数头中:

def extend_prefix(w, letters, results):
        if w in WORDS: results.add(w)
        if w not in PREFIXES: return
        for L in letters:
            extend_prefix(w + L, letters.replace(L, "", 1), results)

同样,您编写函数的方式是,您没有返回一个集合,因此
results=results | result
将爆炸,结果为None类型。

或者,如果您对结果使用默认值None,然后将结果初始化为空集合,则不需要嵌套函数。它稍微简化了您的代码并修复了您的问题。见下文

def find_words(letters, pre = '', results = None):
    if results is None: results = set()
    if pre in WORDS: results.add(pre)
    if pre in PREFIXES:
        for L in letters:
            find_words(letters.replace(L, '', 1), pre+L, results)
    return results

很高兴在StackOverflow上看到另一个Udacity学生

或者,如果对结果使用默认值None,然后将结果初始化为空集,则不需要嵌套函数。它稍微简化了您的代码并修复了您的问题。见下文

def find_words(letters, pre = '', results = None):
    if results is None: results = set()
    if pre in WORDS: results.add(pre)
    if pre in PREFIXES:
        for L in letters:
            find_words(letters.replace(L, '', 1), pre+L, results)
    return results

很高兴在StackOverflow上看到另一个Udacity学生

当我遛狗时,我意识到我不应该设定结果。下次我应该在发帖前遛狗!我以前做过很多次同样的事情。在电脑屏幕前呆了几个小时后,我常常需要休息一下来处理我所学的东西:)我意识到我在遛狗时不应该设定结果。下次我应该在发帖前遛狗!我以前做过很多次同样的事情。在电脑屏幕前呆上几个小时后,我通常只需要休息一下,来处理我所学到的东西:)