编辑以消除多余的混乱:这是一个适用于任意数量的输入列表的解决方案,不会破坏输入列表,也不会复制它们:
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 用户 EOL 提供了我的解决方案的增强版:
def interleave(*args):
iters = sum(([iter(arg)]*len(arg) for arg in args), [])
random.shuffle(iters)
return map(next, iters)
运行这个
a = [1,2,3,4]
b = [5,6,7,8,9]
print interleave(a, b)
产生以下作为许多可能结果之一:
[5, 6, 7, 1, 8, 2, 3, 9, 4]
编辑:应 EOL 的要求,我更新了计时码。不幸的是,由于接受的解决方案修改了它的输入,我需要在每次迭代时制作一个新的副本。我已经为 FJ 和我自己的解决方案做了这个,以使结果具有可比性。以下是 F.Js 解决方案的时机:
$ 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
这是我的函数版本的时间
$ 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
以下是 EOL 增强版的时间安排:
$ 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
如果我从 EOL 增强版本的循环中删除列表复制,我会得到:
$ 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
另一个编辑: FJ 有一个更新的解决方案,并要求我添加时间:
$ 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