12

What's the best/easiest way to shuffle a long list in Mathematica?

Szabolcs
  • 24,728
  • 9
  • 85
  • 174

3 Answers3

20
RandomSample[list]

Yes, it's really that simple. At least since version 6.

Before RandomSample was introduced, one might use:

#[[ Ordering[Random[] & /@ #] ]] & @ list
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
  • 1
    Prior to version 6, I was using `Combinatorica'RandomPermutation`, which is both faster and safer, since it can never produce identical elements. – Leonid Shifrin May 11 '11 at 19:24
  • @Leonid Szabolcs stated: "Combinatorica also has a RandomPermutation function (earlier versions). I am looking for other/better solutions, if there are any." I was answering with that in mind, but that should indeed be a better solution pre-6.0. – Mr.Wizard May 11 '11 at 21:19
  • Oops, missed that one. But then I don't understand - the solution based on `Combinatorica'RandomPermutation` seems superior to me, why bother using `Random` - based one at all (this is a question to @Szabolcs really, not you)? – Leonid Shifrin May 11 '11 at 21:22
  • @Leonid, I was looking for an answer for v8, where Combinatorica is deprecated and issues a warning when loaded. For earlier versions it's fine. – Szabolcs Jun 13 '11 at 15:33
2

Before RandomSample was introduced, I've used the below MathGroup-function heavily, though RandomSample is faster at least by one magnitude on my machine.

In[128]:= n = 10;
          set = Range@n

Out[129]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

In[130]:= Take[set[[Ordering[RandomReal[] & /@ Range@n]]], n]

Out[130]= {8, 4, 5, 2, 3, 10, 7, 9, 6, 1}

Other problem besides performance is that if the same random reals are hit twice (improbable, though possible) Ordering will not give these two in random order.

István Zachar
  • 1,343
  • 2
  • 13
  • 31
  • Pardon me, but that is some dodgy code you have there. (1) `RandomReal[] & /@ Range@n` could be replaced with `Random[] & /@ set` or usually faster `RandomReal[1, Length@set]`. (2) `Take[... , n]` isn't doing anything here, and can be removed. Therefore, the code should be: `set[[ Ordering@RandomReal[1, Length@set] ]]` – Mr.Wizard May 10 '11 at 15:28
  • Actually, using `RandomReal` doesn't make any sense, since it was introduced in version 6 along with `RandomSample`. Therefore, this makes the most sense for pre-version-6 shuffle: `#[[ Ordering[ Random[]& /@ # ] ]] &` – Mr.Wizard May 10 '11 at 15:56
1

Currently I use

list[[PermutationList@RandomPermutation@Length[list]]]

This is for Mathematica 8. Combinatorica also has a RandomPermutation function (earlier versions).

I am looking for other/better solutions, if there are any.

Szabolcs
  • 24,728
  • 9
  • 85
  • 174