Edited to remove superfluous clutter: Here's a solution that works on any number of input lists, doesn't trash the input lists and doesn't copy them either:
import random
def interleave(*args):
iters = [i for i, b in ((iter(a), a) for a in args) for _ in xrange(len(b))]
random.shuffle(iters)
return map(next, iters)
Stackoverflow user EOL has kindly supplied this enhanced version of my solution:
def interleave(*args):
iters = sum(([iter(arg)]*len(arg) for arg in args), [])
random.shuffle(iters)
return map(next, iters)
Running this with
a = [1,2,3,4]
b = [5,6,7,8,9]
print interleave(a, b)
yields the following as one of many possible results:
[5, 6, 7, 1, 8, 2, 3, 9, 4]
Edit: At EOL's request I updated the timing code. Unfortunately, since the accepted solution modifies its inputs, I need to make a fresh copy on each iteration. I've done this for both F.J's and my own solution to make the results comparable. Here's the timing for F.Js solution:
$ python -m timeit -v -s "from srgerg import accepted" -s "a = list(xrange(40000))" -s "b = list(xrange(60000))" "accepted(list(a), list(b))"
10 loops -> 10.5 secs
raw times: 10.3 10.1 9.94
10 loops, best of 3: 994 msec per loop
Here's the timing for my version of the function
$ python -m timeit -v -s "from srgerg import original" -s "a = list(xrange(40000))" -s "b = list(xrange(60000))" "original(list(a), list(b))"
10 loops -> 0.616 secs
raw times: 0.647 0.614 0.641
10 loops, best of 3: 61.4 msec per loop
and here's the timing for EOL's enhanced version:
$ python -m timeit -v -s "from srgerg import eol_enhanced" -s "a = list(xrange(40000))" -s "b = list(xrange(60000))" "eol_enhanced(list(a), list(b))"
10 loops -> 0.572 secs
raw times: 0.576 0.572 0.588
10 loops, best of 3: 57.2 msec per loop
If I remove the list copying from the loop for EOL's enhanced version, I get this:
$ python -m timeit -v -s "from srgerg import eol_enhanced" -s "a = list(xrange(40000))" -s "b = list(xrange(60000))" "eol_enhanced(a, b)"
10 loops -> 0.573 secs
raw times: 0.572 0.575 0.565
10 loops, best of 3: 56.5 msec per loop
Another edit: F.J has an updated solution and asked me to add the timings:
$ python -m timeit -v -s "from srgerg import fj_updated" -s "a = list(xrange(40000))" -s "b = list(xrange(60000))" "fj_updated(list(a), list(b))"
10 loops -> 0.647 secs
raw times: 0.652 0.653 0.649
10 loops, best of 3: 64.9 msec per loop
[1, 2, 3, 4, 5, 6, 7, 8, 9]
is a valid result of random interleaving. Do you want to randomize the period between insertions? – Hoogh