8

I was recently learning how to use random.shuffle in Python and I was surprised to see that the function shuffles the variable in place without returning anything. How is this acheived in the function? Looking at the random library's source code yielded no answer.

How can I write my own function that changes the variable in place without reassignment?

3
  • A function can change the state of its arguments, but it can't replace the arguments with new objects. Imagine an argument you pass to a function is a post-it on a rope. The function can write new things on the post-it, but it can't untie the rope and tie it to a banana. Commented Mar 26, 2014 at 23:58
  • than how does random.shuffle do this? Commented Mar 27, 2014 at 0:07
  • A list's contents are part of its state. random.shuffle doesn't replace the list with a new list; it changes the list's state. Commented Mar 27, 2014 at 0:11

2 Answers 2

6

I is works because of lists are mutable. You cant reassign any variable because it will be new variable. You cant modify immutable typed variable. You can modify mutable variable.

So:

>>> def addone(x):
...     x += 1
>>> a = 2
>>> addone(a)
>>> a
2
>>> def addone(x):
...     x.append(1)
... 
>>> l=[2]
>>> addone(l)
>>> l
[2, 1]
>>> def addone(x):
...     x = x + [1]
... 
>>> li=[2]
>>> addone(li)
>>> li
[2]
Sign up to request clarification or add additional context in comments.

1 Comment

This is the information I was looking for, now I know what to look into (mutable types) kudos
1

Well, just look at the implementation of random.shuffle. Find it in a file called random.py, it's a pure python implementation and quite simple - just using a loop of assignments (with tuple unpacking).

def shuffle(self, x, random=None, int=int):
    """x, random=random.random -> shuffle list x in place; return None.

    Optional arg random is a 0-argument function returning a random
    float in [0.0, 1.0); by default, the standard random.random.

    Do not supply the 'int' argument.
    """

    if random is None:
        random = self.random
    for i in reversed(xrange(1, len(x))):
        # pick an element in x[:i+1] with which to exchange x[i]
        j = int(random() * (i+1))
        x[i], x[j] = x[j], x[i]

3 Comments

yes, but how does this change the value without the return statement?
it is re-assigning x without returning it
It doesn't need to return it. The object x is mutable, so it is modified in place.

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.