Python中的引用错误
这个问题出在 state
这个变量上(在参数中)。在我的代码里,这个变量被修改了(是在 new_state
修改之后)。不过,我听说使用 list()
可以避免这种问题(看起来 state
和 new_state
是指向同一个地方的)。
简单来说,如果我在函数开始时显示 state
的值,然后在返回之前再显示一次,这两个值是不同的(而且我显然不想改变这个变量的值!)。我该怎么解决这个问题呢?
def successor(self, state, numberClients, numberDepots, Q, dist_table):
succ_list = list()
for i in range(0, len(state)):
for j in range(0, len(state[i])):
switchIndex = 0
while switchIndex < length:
permutationIndex = 0
while permutationIndex < len(state[switchIndex]):
new_state = list(state)
temp = new_state[switchIndex][permutationIndex]
new_state[switchIndex][permutationIndex] = new_state[i][j]
new_state[i][j] = temp
if checkConst(new_state): # accept only in some cases (we don't care here)
succ_list.append(('act', new_state))
permutationIndex += 1
switchIndex += 1
return succ_list
2 个回答
0
你自己已经找到了解决办法。在调用的时候:list(...)
,里面的引用会被复制到新的列表中。所以,实际上这不是深拷贝,而是浅拷贝。下面的代码会解释这个问题。
>>> class A: pass
...
>>> a=map(lambda x:A(), range(5))
>>> a
[<__main__.A instance at 0x1018d11b8>, <__main__.A instance at 0x1018f17a0>, <__main__.A instance at 0x101868950>, <__main__.A instance at 0x1018687a0>, <__main__.A instance at 0x101868830>]
>>> b=list(a)
>>> b
[<__main__.A instance at 0x1018d11b8>, <__main__.A instance at 0x1018f17a0>, <__main__.A instance at 0x101868950>, <__main__.A instance at 0x1018687a0>, <__main__.A instance at 0x101868830>]
>>> b[0].v=23
>>> a
[<__main__.A instance at 0x1018d11b8>, <__main__.A instance at 0x1018f17a0>, <__main__.A instance at 0x101868950>, <__main__.A instance at 0x1018687a0>, <__main__.A instance at 0x101868830>]
>>> a[0]
<__main__.A instance at 0x1018d11b8>
>>> a[0].v
23
另外,为了避免这个问题,你可以使用:
import copy
然后,在你的代码中用 new_state = copy.deepcopy(state)
替代 new_state = list(state)
。
下面的代码会解释这个:
>>> import copy
>>> copy.deepcopy
<function deepcopy at 0x1004d71b8>
>>> a=map(lambda x:A(), range(5))
>>> b=copy.deepcopy(a)
>>> b[0].v=23
>>> a[0].v
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute 'v'
2
看起来 state
是一个列表的列表?
当你执行 new_state = list(state)
时,你是在复制外面的那个列表,但复制里面的内容仍然指向原来的内部列表。
试试这个:
new_state = [list(e) for e in state]