The requirements for this one were ([original SO question][1]): * Generate a random-ish sequence of items. * Sequence should have each item N times. * Sequence shouldn't have serial runs longer than a given number (longest below). The solution was actually drafted by another user, this is [my implementation][2] (influenced by [random.shuffle][3]). from random import random from itertools import groupby # For testing the result try: xrange except: xrange = range def generate_quasirandom(values, n, longest=3, debug=False): # Sanity check if len(values) < 2 or longest < 1: raise ValueError # Create a list with n * [val] source = [] sourcelen = len(values) * n for val in values: source += [val] * n # For breaking runs serial = 0 latest = None for i in xrange(sourcelen): # Pick something from source[:i] j = int(random() * (sourcelen - i)) + i if source[j] == latest: serial += 1 if serial >= longest: serial = 0 guard = 0 # We got a serial run, break it while source[j] == latest: j = int(random() * (sourcelen - i)) + i guard += 1 # We just hit an infinit loop: there is no way to avoid a serial run if guard > 10: print("Unable to avoid serial run, disabling asserts.") debug = False break else: serial = 0 latest = source[j] # Move the picked value to source[i:] source[i], source[j] = source[j], source[i] # More sanity checks check_quasirandom(source, values, n, longest, debug) return source def check_quasirandom(shuffled, values, n, longest, debug): counts = [] # We skip the last entries because breaking runs in them get too hairy for val, count in groupby(shuffled): counts.append(len(list(count))) highest = max(counts) print('Longest run: %d\nMax run lenght:%d' % (highest, longest)) # Invariants assert len(shuffled) == len(values) * n for val in values: assert shuffled.count(val) == n if debug: # Only checked if we were able to avoid a sequential run >= longest assert highest <= longest for x in xrange(10, 1000): generate_quasirandom((0, 1, 2, 3), 1000, x//10, debug=True) I'd like to receive any input you have on improving this code, from style to comments to tests and anything else you can think of. [1]: https://stackoverflow.com/q/4630723/555569 [2]: https://stackoverflow.com/questions/4630723/using-python-for-quasi-randomization/4630784#4630784 [3]: http://svn.python.org/view/python/trunk/Lib/random.py?view=markup#shuffle