0

in this program I'm trying to shuffle a list by randomly choosing two items from a list and swapping them round, and then repeating this process several times.

The problem I have encountered is I don't know how I can swap the items round and print the shuffled list.

For instance if my two random values were a and b, if I were to just put:

a = b
b = a

then that would change the value of a to b, but when it tries to change b to a, no change would occur as a has already been changed to b.

The only way I can think that this would work is swapping them at the same time, but I do not know of a function/ way to swap them round.

Also if a, b were items of a list L, after I swapped them round if I used

print L

should it print the altered version? I only ask because from what I have tried it is not doing that.

NB I am trying to shuffle this list stage by stage by swapping, instead of using the shuffle function imported from random.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
George Burrows
  • 3,391
  • 9
  • 31
  • 31
  • The classic way of swapping back when I were a lad, was to use a temporary variable: tmp=a, a=b, b=tmp - but python is smarter than BASIC was then! [too lame to deserve to be an answer] – Spacedman Nov 16 '11 at 17:25

5 Answers5

4

In Python, you can swap two variables like this:

a, b = b, a

This is called multiple assignment, you can find more information about it here.

In other languages this is usually done by assigning a temporary variable:

tmp = a
a = b
b = tmp

Isn't Python great?

Community
  • 1
  • 1
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
4

The random.shuffle function uses swapping too. It would be worthwhile to look at its source code:

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.
    """

    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]

Observe how the last line performs a swap using tuple packing and unpacking.

As an alternative to packing and unpacking, the traditional way to swap variables is to use a temporary variable:

t    = x[i]
x[i] = x[j]
x[j] = t
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
3

Use a temp variable for your first problem:

temp = a
a = b
b = temp

In Python you can also do this:

a, b = b, a

I suspect your second problem is because you're changing things you got out of the list, instead of changing the list. Try this:

i, j = # two indexes to swap in the list
L[i], L[j] = L[j], L[i]
Brendan Long
  • 53,280
  • 21
  • 146
  • 188
1

Use a temporary variable:

temp = a
a = b
b = temp
Oliver
  • 11,297
  • 18
  • 71
  • 121
0

http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

Just swapping items is known to be bad.

Don't forget that if you have n items, there are n! arrangements. If your random number is 32 bits, there are 2^32 numbers.

It's hard then to shuffle a pack of cards with a 32 bit number as 52! is very much bigger than 2^32

Nickle
  • 367
  • 3
  • 5