Atul
Atul

Reputation: 536

Strange output using random python

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

Answers (4)

Cyrbil
Cyrbil

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

nauer
nauer

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

DocZerø
DocZerø

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

user6451264
user6451264

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

Related Questions