反向方法变异输入

时间:2012-05-31 20:25:32

标签: python iteration mutation

对于赋值,我们被要求创建一个函数来反转任意嵌套列表中的所有元素。因此函数的输入应该返回如下内容:

>>> 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

但是对于一些个人挑战,我想在不使用递归的情况下创建解决方案。这种尝试的一个版本导致了一些我不理解的奇怪行为。为了澄清,我不希望这个版本正常工作,但结果输入突变没有意义。这是有问题的迭代版本:

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所做的那样,我会避免改变输入。然而,一些印刷语句后来发现反向方法有一个改变原始列表的手。那是为什么?

2 个答案:

答案 0 :(得分:3)

list()调用正在创建一个新列表,其中包含来自原始列表的浅层复制列表。

试试这个(从here被盗):

from copy import deepcopy
listB = deepcopy(listA)

答案 1 :(得分: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()创建列表副本时,您会看到列表仍然引用相同的对象。