0

I am trying to generate three different arrays of vx[], vy[] and vz[] for 2 atoms (natoms). I am able to print these different values when I initialize the arrays just after the initialization. However, when I try to print the values later it give the same array, ie. vz[] for all the arrays vx[], vy[] and vz[]. Am I missing something? I tried using different loops, but still cannot get it. I also tried copying the arrays in new arrays, as velx (=vx), vely and velz but its of no use. Could someone please tell what am I doing wrong?

    for i in xrange(0,natoms,1):
            x = random.random()
            vx[i]=4.0*math.sqrt(vtotsq)*(x-0.5)
            print '1st %f' % (vx[i]) # prints the value here
    print (vx)
    velx = vx
    for i in xrange(0,natoms,1):
            y = random.random()
            vy[i]=4.0*math.sqrt(vtotsq)*(y-0.5)
            print '2nd %f' % (vy[i])
    print (vy)
    vely = vy
    for i in xrange(0,natoms,1):
            z = random.random()
            vz[i]=4.0*math.sqrt(vtotsq)*(z-0.5)
            print '3rd %f' % (vz[i])
    print (vz)
    velz = vz

    for i in xrange(0,natoms,1):
            print 'vx %d is %f' %(i,vx[i])

    print (vx)
    print '\n'
    print (vy)
    print '\n'
    print (vz)
    print '\n'
    print (velx)   # unfortunately veld, vely and velz all are still the same equal to vz
    print '\n'
    print (vely)
    print '\n'
    print (velz)

1 Answer 1

2

All of your lists are simply references to the same list object, so changing one appears to change them all. To actually copy a list, you can slice the whole thing:

velx = vx[:]

or explicitly create a new list:

velx = list(vx)

But the neatest way to do what you want is a list comprehension, which creates and fills the list in one step:

vx = [4.0 * math.sqrt(vtotsq) * (random.random() - 0.5) for _ in range(natoms)]

Or, better:

vtotsqrt = math.sqrt(vtotsq) # sqrt is hard, do this once
vx = [4 * vtotsqrt * (random.random() - 0.5) for _ in range(natoms)]

Note that range(0, x, 1) is equivalent to range(x). Assuming you want the three lists to contain different random values, you should run this three times rather than copying the lists.

Sign up to request clarification or add additional context in comments.

5 Comments

Or you can use vy = list(vx) which provides better self-documentation and is clearer to beginners than slicing
I tried both the methods, they work fine. Thanks a lot. But I am still not very clear where I am referencing to the same 'list'. Could you please elaborate, I am relatively new to Python. Thanks a lot again.
You don't actually show in your code where you originally create vx, vy and vz, you just start changing elements in them (vx[i] = ...). If you add the earlier code, I will update my answer accordingly.
I see what you are telling. Ok, so if I initially created all these arrays separately, initialized them with zero and then tried to change these values according to my code, will that work?
Yes, but you could create empty lists [] and .append() the values, rather than filling with zeroes to begin with.

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.