3

During my work with python I've met one blocking problem. I have SomeFunction which should do some simple calculation (and also sorting it - I remove that piece of code for keep it more clear) over given vector of integers and return new one. Main problem is, that result of each inside loop must become an input for next one but variable k and X seems to have the same address in memory.

Function looks like this:

def SomeFunction(k, N):
    X = range(N);
    for i in range(N):
        for j in range(3):
            X[i] = k[i]*2;
        print "X:";
        print X;
        print "k -> :";
        print k
        k = X;
        print "============================";
    return k;

and it produce output:

    X:
    [0, 1, 2, 3, 4, 5, 6, 7]
    k -> :
    [0, 1, 2, 3, 4, 5, 6, 7]
    ============================

    X:
    [0, 8, 2, 3, 4, 5, 6, 7]
    k -> :
    [0, 8, 2, 3, 4, 5, 6, 7]
    ============================

Output for first loop is ok, because first element is 0, but then for the rest of the loops you can see the problem. X should have new value while k should be the same. Does anyone have any idea how solve this problem?

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
PiotrK
  • 99
  • 2
  • 9
  • 2
    python doesn't need the ';' as a line terminator – Back2Basics Jan 02 '14 at 08:52
  • possible duplicate of [Wrong list being returned in python](http://stackoverflow.com/questions/20019547/wrong-list-being-returned-in-python) – thefourtheye Jan 02 '14 at 08:54
  • I honestly have a hard time counting this as a duplicate. There is more than a couple questions with the very same answer and underlying problem as this one. But I am not sure if one should consider questions or problems the same, even if the answer is. – luk32 Jan 02 '14 at 08:56

4 Answers4

5

When you say

k = X;

You are not creating a copy of X into k, but you are making both X and k point to the same list. You can create a copy of the list like this

k = X[:]

Note: Python doesn't expect ; at the end of the line.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
2

You can use slice notation to copy an array content to another, preserving the list ID:

k[:] = X[:]
justhalf
  • 8,960
  • 3
  • 47
  • 74
1

try this:

def SomeFunction(k = range(8),N=8):
    X = range(N)
    for i in range(N):
        for j in range(3):
            X[i] = k[i]*2
        print "X:"
        print X
        print "k -> :"
        print k
        k = X[:]
        print("============================")
    return k

SomeFunction()
Back2Basics
  • 7,406
  • 2
  • 32
  • 45
-1

Well I am not sure whether this should be posted as answer or comment, but this covers your problem wholly: python list by value not by reference.

I decided for an answer to give an explanation.

Python by default uses references in cases like this. So you are right, the X and k essentially point to the same instance of the list. What you want is to make a deep copy of the contents.

Community
  • 1
  • 1
luk32
  • 15,812
  • 38
  • 62