0

割り当てについては、任意にネストされたリスト内のすべての要素を逆にする関数を作成するように求められました。したがって、関数への入力は次のようなものを返す必要があります。

>>> seq = [1,[2,[3]]]
>>> print arb_reverse(seq)
[[[3],2],1]
>>> seq = [9,[[],[0,1,[[],[2,[[],3]]]],[],[[[4],5]]]]
>>> print arb_reverse(seq)
[[[[5,[4]]],[],[[[[3,[]],2],[]],1,0],[]],9]

私はうまく機能する再帰的な解決策を思いついた:

def arb_reverse(seq):
    result = []
    for element in reversed(seq):
        if not is_list(element):
            result.append(element)
        else:
            result.append(arb_reverse(element))
    return result

しかし、少し個人的な挑戦のために、再帰を使用せずにソリューションを作成したかったのです。この試みの1つのバージョンは、私が理解していないいくつかの奇妙な振る舞いをもたらしました。明確にするために、私はこのバージョンが正しく機能することを期待していませんでしたが、結果として生じる入力ミューテーションは意味がありません。問題の反復バージョンは次のとおりです。

def arb_reverse(seq):
    elements = list(seq)   #so input is not mutated, also tried seq[:] just to be thorough
    result = []
    while elements:
        item = elements.pop()
        if isinstance(item, list):
            item.reverse() #this operation seems to be the culprit
            elements += item 
        else:
            result.append(item)
    return result

これはフラット化された半反転リストを返します(ある程度期待されます)が、興味深い部分は入力に対して何をするかです(期待されていません)...

>>> a = [1, [2, [3]]]
>>> arb_reverse(a)
[2, 3, 1]
>>> a
[1, [[3], 2]]
>>> p = [1, [2, 3, [4, [5, 6]]]]
>>> print arb_reverse(p)
[2, 3, 4, 5, 6, 1]
>>> print p
[1, [[[6, 5], 4], 3, 2]]

list()入力に含まれる値を、を使用して、または使用したように変数に渡すinput[:]ことで、入力elementsの変更を回避できるという印象を受けました。ただし、後でいくつかのprintステートメントにより、逆の方法が元のリストの変更に役立つことが明らかになりました。何故ですか?

4

2 に答える 2

3

list()呼び出しは、元のリストから浅くコピーされたリストを使用して新しいリストを作成しています。

これを試してください(ここから盗まれました):

from copy import deepcopy
listB = deepcopy(listA)
于 2012-05-31T20:32:15.267 に答える
2

このツールを使用して次のコードを実行してみてくださいhttp://people.csail.mit.edu/pgbovine/python/tutor.html

o1 = [1, 2, 3]
o2 = [4, 5, 6]

l1 = [o1, o2]

l2 = list(l1)

l2[0].reverse()

print l2
print l1

具体的には、l2[0].reverse()が呼び出されたときに何が起こるかを見てください。

リストのコピーを作成するために呼び出すlist()と、リストは同じオブジェクトを参照していることがわかります。

于 2012-05-31T20:32:16.863 に答える