Reputation: 536
i have this problem where i sort a list based on randomness. how the algorithm works is two select a random number between 0 to N-1 (N is length of list) and swap with a iterating index.
i have two different algorithms like this.
import random
def algo1(xx):
for i in xrange(len(xx)):
p = random.randrange(i, len(xx)) # random number between i and len(xx) - 1
xx[i], xx[p] = xx[p], xx[i]
return xx
def algo2(yy):
for i in xrange(len(yy)):
p = random.randrange(0, len(yy)) # random number between 0 and len(xx) - 1
yy[i], yy[p] = yy[p], yy[i]
return yy
k = range(5)
print algo1(k)
print algo2(k)
here everything works fine. i print the return values from algo1 and algo2.
But when i store the return values in variables
z1 = algo1(k)
z2 = algo2(k)
print z1
print z2
they both contain the same list. how many times i run they show the same return values
see this video https://www.youtube.com/watch?v=ZBjlnaCLKsQ&feature=youtu.be
Upvotes: 0
Views: 75
Reputation: 6478
Your function alters k
and returns a reference to it. There is no new list
being created.
The difference in what you are seeing is:
When you print, you show the current state of what algoX
has returned (which is a reference to k
).
When you assign the result, you set z1
and z2
to a reference of k
, meaning z1 is z2 is k
. And you only print after, when you finished manipulating k
. That's why you see the same result, all theses 3 variables have the same reference to the same list.
Upvotes: 2
Reputation: 700
Try this:
z1 = algo1(k)
print z1
z2 = algo2(k)
print z2
print z1
print k
You are simply overwrite the same list. Google for "python Immutable vs Mutable types" to understand this behaviour.
Upvotes: 1
Reputation: 8557
As you're passing, modifying and returning the same variable (list) k
to both functions, you're modifying the same data each time.
Try using:
print("z1", id(z1))
print("z2", id(z2))
print("k", id(k))
This will return the identity of the variable. You'll notice that z1, z2 and k all have the same identity.
In the first case, you're printing the output directly, before calling the next function. This is why you didn't notice this behaviour.
However, when you're assigning the return variable, saving it and then printing it, you'll notice the issue.
To resolve it, instead of modifying the list that you've passed into the function, create a new list inside of the function, assign the values to it and return that list.
Upvotes: 1
Reputation:
You are modifying the list (I am assuming you’re on python 2.7) in place. Thus, when you shuffle the k
with algo2
, you are also affecting z1
. All three lists are really the same object. You need to create a list copy, for example algo1(k[:])
.
I would also take a look at random.shuffle
, which does pretty much the thing you want. Note that random.shuffle
also modifies the input in place, so you will need [:]
too.
Upvotes: 2