1

The problem comes from the state variable (in args). It is modified in my code (after the new_state modifications). However, I've read that using list() could prevent this kind of problem (it looks like state and new_state have the same reference).

To sum up, if I display the value of state at the beginning of the function, and just before the return, the values are different (and I obviously don't want to change the value of this variable !). How can I solve this problem ?

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
0

2 Answers 2

2

It looks like state is a list of lists?

When you do new_state = list(state), you are copying the outer list, but the references inside the copy still point to the same inner lists.

Try this:

new_state = [list(e) for e in state]
Sign up to request clarification or add additional context in comments.

Comments

0

You have found the solution yourself. The references in the call: list(...) are copied to the new list. So essentially, it is not a deep copy but a shallow copy. The following code explains it.

>>> 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

Also, in order to prevent the problem, you can use:-

import copy

And, then, use new_state = copy.deepcopy(state) in your code instead of new_state = list(state).

The following code explains this:-

>>> 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'

1 Comment

Ok deepcopy will do the trick, thanks guys ! It's a list of lists yeah.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.