sz = input('Enter the size of the board: ')
board = [[0 for j in xrange(sz)] for i in xrange(sz)]
for row in range(sz):
for col in range(sz):
board[row][col] = input()
pqval = 1
steps = 2
start_state = sz , board , pqval ,steps
t=1
for row in range(sz):
for col in range(sz):
board[row][col] = t
t=t+1
board[sz-1][sz-1] = 0
end_state = sz, board , pqval ,steps
print "Here is the starting position: "
print start_state
print "Here is the ending position: "
print end_state
我无法理解为什么更改也会在start_state的board属性中发生,即使它是在之前构建的。我肯定做了一些愚蠢的事。 python的新手来自C / C ++背景,这种行为似乎很奇怪。
如果我希望元组具有所有4个值并且希望更改一个元组的属性而不将其复制到任何地方,那么该怎么办?
答案 0 :(得分:1)
在Python中,赋值与C ++非常不同;事实上,变量的概念是不同的。
* ...通常;你可以覆盖它来表示你想要的任何东西。
**好吧,任何正数。一旦它没有名称,它将被垃圾收集器清理。
你可能在简单的情况下知道这一点:
>>> a = [0]
>>> b = a
>>> b[0]
0
>>> a[0] = 1
>>> b[0]
1
但在每个案例中都是如此。所以,当你这样做时:
start_state = sz , board , pqval ,steps
...只是意味着start_state[1]
成为同一个board
对象的另一个名称。 start_state[1]
是一个“复杂目标”而不是一个普通变量的事实并不重要;您通过分配到start_state
而不是直接分配给start_state[1]
而间接创建它的事实并不重要;它仍然是一个名字。
当然sz
,pqval
和steps
也是如此,但你永远不会改变这些值 - 因为你不能;字符串和数字不能改变。
重新分配pqval
不会将1
变为其他数字; *只会使pqval
成为其他号码的名称,而start_state[2]
仍然是原来的。同样,重新分配board
也不会影响start_state[1]
。它只是在原位变异board
。
*如果你能做到这一点,那将是一个超级大国的地狱,但任何使用它都可能打破宇宙......
当你使用像+=
之类的运算符时,这会变得有点棘手,特别是如果你已经习惯了C ++。在C ++中,+=
总是意味着改变一个变量,无论它是否意味着改变一个值;当你无法改变变量时,+=
就行不通了。在Python中,没有“变异变量”这样的东西;它总是意味着重新分配变量,无论它是否意味着改变一个值;当你无法改变某个值时,+=
只会重新分配一个新值。
如果要制作副本,则必须明确地进行复制。例如,任何这些都可行:
start_state = sz, board[:], pqval, steps
start_state = sz, copy.copy(board), pqval, steps
start_state = copy.deepcopy((sz, board, pqval, steps))
或者,或者,您可以使board
的工作方式与其他对象相同 - 从不改变它,只将其重新分配给新列表。例如,而不是:
board[row][col] = t
......你可以这样做:
board = [[val if i, j != row, col else t for j, val in enumerate(row)]
for i, row in enumerate(board)]
当然这有点傻,但通常你可以将循环重写为生成新列表的列表理解,并且不愚蠢。例如:
board = [[i*sz+j for j in range(sz)] for i in range(sz)]