Python列表中的不必要行为

2024-06-01 04:50:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将一个矩阵表示为一个列表列表,并根据矩阵中的位置是否满足某些条件用值填充它。我存储它的变量是self._solution。你知道吗

为了继续,我采取了两种不同的方法: 方法1:

def __init__(self, N=3, puzzle=None):
        self.N = N
        self.SIZE = self.N*self.N
        self.puzzle = [[set([1])]*(self.SIZE)]*(self.SIZE)
        if puzzle is None:
            for i in range(self.SIZE):
                self.puzzle[i] = [int(k) for k in raw_input()]
        else:
            self.puzzle = [[int(k) for k in line] for line in puzzle.splitlines()]

        self._empty_cells = 0    
        self._solutions = [[0]*(self.SIZE)]*(self.SIZE)
        self._solutions = []
        print self.puzzle
        print self._solutions
        for i in range(self.SIZE):
            self._solutions.append([])
            for j in range(self.SIZE):
                if self.puzzle[i][j] < 1:
                    #self._solutions[i][j] = set(range(1,self.SIZE+1))
                    self._solutions[i].append(1)
                    self._empty_cells += 1
                    print "puzzle[%s][%s] = %s\tsolutions[%s][%s] = %s" % (i,j, self.puzzle[i][j], i, j, self._solutions[i][j])
                else:
                    self._solutions[i].append(0)
        print self._solutions

方法2:

def __init__(self, N=3, puzzle=None):
        self.N = N
        self.SIZE = self.N*self.N
        self.puzzle = [[set([1])]*(self.SIZE)]*(self.SIZE)
        if puzzle is None:
            for i in range(self.SIZE):
                self.puzzle[i] = [int(k) for k in raw_input()]
        else:
            self.puzzle = [[int(k) for k in line] for line in puzzle.splitlines()]

        self._empty_cells = 0    
        self._solutions = [[0]*(self.SIZE)]*(self.SIZE)
        #self._solutions = []
        print self.puzzle
        print self._solutions
        for i in range(self.SIZE):
            #self._solutions.append([])
            for j in range(self.SIZE):
                if self.puzzle[i][j] < 1:
                    #self._solutions[i][j] = set(range(1,self.SIZE+1))
                    self._solutions[i][j] = 1
                    #self._solutions[i].append(1)
                    self._empty_cells += 1
                    print "puzzle[%s][%s] = %s\tsolutions[%s][%s] = %s" % (i,j, self.puzzle[i][j], i, j, self._solutions[i][j])
        print self._solutions

我考虑的是self._solution的值是如何设置的。理想情况下,这两种方法都应该工作得最好,但是这两种方法的输出有很大的不同。我只希望满足条件self.puzzle[i][j] == 0的位置设置为1。但是,在方法2中,self._solution的所有值都设置为1,而方法1工作正常。你知道吗

同样在方法2中,如果我只是在if self.puzzle[i][j] == 0条件之后添加一个else块,然后设置self._solution[i][j] = 0的值,那么输出是正确的。你知道吗

有人能解释这种奇怪的行为吗。有没有其他人也看到过类似的结果。你知道吗

我正在使用iPython和python2.7

Edit:它不是unexpected behaviour of nested lists in python的副本,因为它处理@Crazy Casta指出的*操作符。我还发现我有这样的情况: self._solutions = [[set([])]*SIZE]*SIZE更危险,因为每个创建的set元素都指向内存中的同一个元素。你知道吗


Tags: 方法inselfnoneforsizeifrange
1条回答
网友
1楼 · 发布于 2024-06-01 04:50:53

有很多需要接受,但我猜你在这方面遇到了麻烦:

self._solutions = [[0]*(self.SIZE)]*(self.SIZE)

假设你要做的是制作self.SIZE大小独立的列表self.SIZE,那么你就得不到你想要的。您正在使用的列表乘法语法复制引用,因此您有一个指向同一列表的self.SIZE引用列表。你想要的是:

self._solutions = [[0]*(self.SIZE) for _ in range(self.SIZE)]

这将创建一个新的列表self.SIZE次,而不是重复使用同一个列表。你知道吗

相关问题 更多 >