Python中的引用错误

1 投票
2 回答
1308 浏览
提问于 2025-04-17 19:20

这个问题出在 state 这个变量上(在参数中)。在我的代码里,这个变量被修改了(是在 new_state 修改之后)。不过,我听说使用 list() 可以避免这种问题(看起来 statenew_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]

撰写回答