0

I am pretty new to python and I am trying to swap the values of some variables in my code below:

def MutationPop(LocalBestInd,clmns,VNSdata):

    import random

    MutPop = []
    for i in range(0,VNSdata[1]):

        tmpMutPop = LocalBestInd

        #generation of random numbers
        RandomNums = []
        while len(RandomNums) < 2:
            r = random.randint(0,clmns-1)
            if r not in RandomNums:
                RandomNums.append(r)
        RandomNums = sorted(RandomNums)

        #apply swap to berths
        tmpMutPop[0][RandomNums[0]] = LocalBestInd[0][RandomNums[1]]
        tmpMutPop[0][RandomNums[1]] = LocalBestInd[0][RandomNums[0]]

        #generation of random numbers
        RandomNums = []
        while len(RandomNums) < 2:
            r = random.randint(0,clmns-1)
            if r not in RandomNums:
                RandomNums.append(r)
        RandomNums = sorted(RandomNums)

        #apply swap to vessels

        tmpMutPop[1][RandomNums[0]] = LocalBestInd[1][RandomNums[1]]
        tmpMutPop[1][RandomNums[1]] = LocalBestInd[1][RandomNums[0]]

        MutPop.append(tmpMutPop)

    Neighborhood = MutPop
    return(Neighborhood)

my problem is that I do not want to change the variable "LocalBestInd" and want to use it as a reference to generate new "tmpMutPop"s in the loop, but the code put "LocalBestInd" equal to "tmpMutPop" every time that loop is iterated. The same problem happens for other assignments (e.g., tmpMutPop[1][RandomNums[1]] = LocalBestInd[1][RandomNums[0]]) in this code.

Would you please help me to solve this problem?

Thank you

Masoud

  • You specifically made `LocalBestInd` and `tmpMutPop` refer to the same list structure. First, you need `tmpMutPop = copy.deepcopy(LocalBestInd)`. That should get you moving. Before you post again, please repeat the intro tour, especially expected [MRE](https://stackoverflow.com/help/minimal-reproducible-example). This posting needs a lot of sculpting to make a viable Stack Overflow question. – Prune Apr 11 '20 at 20:54
  • Does this answer your question? [How to clone or copy a list?](https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list) – Meto Apr 11 '20 at 21:21

2 Answers2

0

Assuming that LocalBestInd is a list, the problem, I think, is that when you're setting

tmpMutPop = LocalBestInd

in the loop, the value tmpMutPop is not a separate list but is just a reference to the list LocalBestInd, which actually contains the data. There's only one list - when you try to update the former, you're really only updating the latter.

Simple example of this works here:

>>> x = [1, 2]; y = x; y[0] = 2; print(x)
[2, 2]

What may help you here is calling .copy() on your list, e.g.:

>>> x = [1, 2]; y = x.copy(); y[0] = 2; print(x)
[1, 2]

If that doesn't work then check out the other list copying methods in this SO answer: How to clone or copy a list?

davidshere
  • 315
  • 3
  • 10
0

Try this:

import copy

And change the line

tmpMutPop = LocalBestInd

to this:

tmpMutPop = copy.copy(LocalBestInd)

Depending on the structure of LocalBestInd, you may need copy.deepcopy() instead.

Here's a quote from the copy documentation that explains what's going on:

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.

Arne
  • 9,990
  • 2
  • 18
  • 28