在Python中,有一个常见的问题是,当在一个元组中改变一个值时,这个改变会反映在所有引用该元组的其他变量中。这使得很难保持变量的独立性,并可能导致难以追踪的错误。例如,以下代码演示了这个问题:
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
运行这段代码,你会发现,当你在循环中改变board中的值时,start_state中的board值也会发生改变。这是因为在Python中,元组中的值是引用,而不是副本。这意味着,当你在一个元组中改变一个值时,你实际上是在改变所有引用该元组的其他变量中的值。
解决方案
有几种方法可以解决这个问题。一种方法是使用copy.deepcopy()函数来创建元组的副本。copy.deepcopy()函数会创建一个元组的新副本,其中包含原始元组中所有值的副本。这意味着,当你改变副本中的值时,原始元组中的值不会受到影响。
import copy
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 , copy.deepcopy(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
另一种方法是使用元组的切片操作符来创建元组的副本。元组的切片操作符会创建一个元组的新副本,其中包含原始元组中指定范围的值。这意味着,当你改变副本中的值时,原始元组中的值不会受到影响。
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
最后,你还可以使用列表推导式来创建元组的副本。列表推导式会创建一个列表的新副本,其中包含原始列表中指定范围的值。这意味着,当你改变副本中的值时,原始列表中的值不会受到影响。
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 , [row[:] for row in 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