素材牛VIP会员
在python的class里操作list的奇怪错误
 逆***团  分类:Python  人气:992  回帖:2  发布于6年前 收藏

今天在做一个简单的python类时发现一个奇怪的问题,无法正常操作list。
以下是代码,主要是写一个类来生成给定数的全排列。

class permutation(object):
    def __init__(self,initArray):
        self.__permResult = []
        if len(initArray) > 1:
            self.generatePerm(0,initArray)
        else :
            self.__permResult = initArray

    def generatePerm(self,i,array):
        if i < len(array) :
            for index in range(i,len(array)):
                array[i],array[index] = array[index],array[i]
                self.generatePerm(i+1,array)
                array[i],array[index] = array[index],array[i]

        else :
            print(array)
            self.__permResult.append(array)
#           changing the above line to:
#           self.__permResult = self.__permResult + array 
#           would give me something like [1,2,3,1,3,2,2,1,3,2,3,1,3,1,2,3,2,1]

    def printResult(self):
        print(self.__permResult)

test = permutation([1,2,3])
test.printResult()

但是很奇怪地得到了如下结果

[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 2, 1]
[3, 1, 2]
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]

全排列是出来了但却没法(通过append方法)添加到__permResult这个list里面,但以前又没遇到过这种奇怪的情况。
虽然我有感觉这是个很蠢的问题,但看了很久也无法找出错误,只好来segmentfault麻烦大家了。谢谢!


然而如果把append方法的参数改成(array[0:]),则可以正常工作。原来的append(array)则不能,这实在太奇怪了。不知道是bug还是feature

 标签:python

讨论这个帖子(2)垃圾回帖将一律封号处理……

Lv1 新人
真***溜 职业无 6年前#1
self.__permResult.append(array[:])

引用,浅拷贝,和深拷贝。题主只是引用,如果list里没有list或者dict等,可以进行浅拷贝。否则,应该进行深拷贝。可以参考下面的例子。

import copy
l = [1,2,3,[4,5]]

l2 = l
l3 = l[:]
l4 = copy.copy(l)        #浅拷贝
l5 = copy.deepcopy(l)    #深拷贝

l[-1].append('change')
l.append(6)

print l2
print l3
print l4
print l5
# [1, 2, 3, [4, 5, 'change'], 6]
# [1, 2, 3, [4, 5, 'change']]
# [1, 2, 3, [4, 5, 'change']]
# [1, 2, 3, [4, 5]]

如果全排列,可以引用标准库中的 itertools

In [6]: list(itertools.permutations([1,2,3], 3))
Out[6]: [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
Lv3 码奴
随***火 站长 6年前#2

append(array)方法只是把array的引用放进去了,并没有拷贝array。
通过id(array)可以验证

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取