3

リスト内包表記で再帰的にプログラムされたPythonの関数があります。しかし、実際に何が起こっているのかはっきりとはわかりません!

def permut(s,l):
    if l == []: return [[s]]
    return [ e + [l[0]] for e in permut(s, l[1:])] + [l+[s]]

この関数は 2 つの引数を取得します。1 つ目は文字列、2 つ目はリストで、リスト内の文字列の順列を返します。

permut('a', [1,2,3])
[['a', 3, 2, 1], [3, 'a', 2, 1], [2, 3, 'a', 1], [1, 2, 3, 'a']]

リスト内包表記で何が起こるか、誰か説明できますか?

4

2 に答える 2

2

まず第一に、a代わりsに再帰permut呼び出しがあります。

return [ e + [l[0]] for e in permut(a, l[1:])] + [l+[s]]

まず、 を計算します。つまり、最初の要素のないリストの部分permut(s, l[1:])を並べ替えようとします。s最初の要素があれば破棄し、再帰呼び出しは [[s]] を返します。

現在、呼び出しで逆方向に移動すると、s再帰的に作成されたリストのすべての要素に「追加」され、指定lされたものが追加され、結果は次のようになります。

# l == []
return [['a']]

# e == ['a']
# l == [3], l[0] == 3
return [['a'] + [3]] + [[3] + [a]]
# equals [['a', 3], [3, 'a']]

# e == ['a', 3] then [3, 'a']
# l == [2, 3], l[0] == 2
return [['a', 3] + [2], [3, 'a'] + [2]] + \
        [[2, 3] + [a]]
# equals [['a', 3, 2], [3, 'a', 2], [2, 3, 'a']]

# e == ['a', 3, 2] then [3, 'a', 2] then [2, 3, 'a']
# l == [1, 2, 3], l[0] == 1
return [['a', 3, 2] + [1], [3, 'a', 2] + [1], [2, 3, 'a'] + [1]] + \
        [[1, 2, 3] + ['a']]
# equals [['a', 3, 2, 1], [3, 'a', 2, 1], [2, 3, 'a', 1], [1, 2, 3, 'a']]

読むのは美しくないかもしれませんが、うまくいきます。e前のレベルで返されたリストの単一要素として抽出されていることがわかります。

あなたも試すことができます:

def tee(parm):
    print parm
    return parm

そして、次のように再定義permutします。

def permut(s,l):
    if l == []: return [[s]]
    return [ e + [l[0]] for e in tee(permut(s, l[1:]))] + [l+[s]]

私の出力:

[['a']]
[['a', 3], [3, 'a']]
[['a', 3, 2], [3, 'a', 2], [2, 3, 'a']]
[['a', 3, 2, 1], [3, 'a', 2, 1], [2, 3, 'a', 1], [1, 2, 3, 'a']]

これは再帰呼び出しをカバーします。

于 2013-04-16T07:42:36.133 に答える