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結果がNone Typeで爆発したでしょう。

于 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 に答える