我试图将矩阵表示为列表列表,并使用基于天气的值填充矩阵,矩阵中的位置满足某些条件。我存储的变量是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和Python 2.7
编辑:它不是unexpected behaviour of nested lists in python的副本,因为这个处理@Crazy Casta指出的*运算符。我也想到了我有这样的事情的情况:
self._solutions = [[set([])]*SIZE]*SIZE
更加危险,因为每个创建的set元素都指向内存中的同一元素。
答案 0 :(得分:1)
要接受很多,但我猜你在这方面遇到了麻烦:
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
次,而不是重复使用相同的列表。