riffle is simpler and works better
[riffle.git] / util / riffle.py
blobec1f7adee841e5650a357b9a9cfbc1f23b56ddf5
2 def riffle(lol):
3 """
4 given list of lists return flat list of elements, riffled:
5 - order of individual lists is preserved
6 - elements of the same list are far apart
8 (this really should be called "false riffle" because
9 it doesn't shuffle, or "perfect riffle" for the same
10 reason. consult youtube for the card shuffle technique
11 that inspired the name)
12 """
13 def merge(a, b):
14 "does not modify either, returns merged list"
15 if len(a) == 0:
16 return b
17 elif len(b) == 0:
18 return a
19 elif len(a) > len(b):
20 x = a
21 a = b
22 b = x
23 c = []
24 r = float(len(a)) / len(b)
25 i_a = 0
26 for i_b in xrange(len(b)):
27 if r*(i_b) > i_a:
28 c.append(a[i_a])
29 i_a += 1
30 c.append(b[i_b])
31 return c
33 res = lol[0]
34 for i in lol[1:]:
35 res = merge(res,i)
36 return res
38 def test_riffle():
39 def gen_taglist(prefix, amount):
40 return [prefix+str(i) for i in xrange(amount)]
42 def print_lst(lst):
43 for x in lst:
44 print x, " ",
45 print
47 for i in xrange(10):
48 print_lst( riffle( [gen_taglist(chr(a+ord('a')),
49 random.randint(2,13))
50 for a in range( random.randint(1,10))] ))
51 print