0

我有以下 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

它显然无法在对extend_prefix 的递归调用中找到结果。为什么会这样,我该如何解决?

4

2 回答 2

2

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

Python 范围/命名空间

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结果会被炸毁,结果是无类型。

于 2012-08-14T00:12:27.410 回答
1

或者,如果您对结果使用默认值 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 学生!

于 2012-08-14T00:44:50.117 回答