<br>Here's a baroque way to do it using generated code:<br><br><div style="margin-left: 40px;"> def cg_combinations(seqs):<br> n = len(seqs)<br> chunks = ["def f(%s):" % ', '.join('s%s' % i for i in range(n))]
<br> for i in reversed(range(n)):<br> chunks.append(" " * (n -i) + "for x%s in s%s:" % (i, i))<br> chunks.append(" " * n + " yield (" + ', '.join('x%s' % i for i in range(n)) + ')')
<br> code = '\n'.join(chunks)<br> exec code<br> return f(*seqs)<br><br></div>It should be reasonably fast, if non-obvious. I've included a version with some timing and testing against Chucks version below. Enjoy.
<br><br>(Also, it can be simplified slightly, but I wanted to generate in the same order as Chuck for comparison purposes).<br><br><br>======================================================================<br><br><br> def count(seqs) :
<br> counter = [0 for i in seqs]<br> maxdigit = [len(i) - 1 for i in seqs]<br> yield counter<br> while True :<br> i = 0;<br> while i < len(counter) and counter[i] >= maxdigit[i] :
<br> counter[i] = 0<br> i += 1<br> if i < len(counter) :<br> counter[i] += 1<br> yield counter<br> else :<br> return<br>
<br> def count_combinations(seqs):<br> for c in count(seqs):<br> yield tuple(s[i] for (s, i) in zip(seqs, c))<br> <br> def cg_combinations(seqs):<br> n = len(seqs)<br> chunks = ["def f(%s):" % ', '.join('s%s' % i for i in range(n))]
<br> for i in reversed(range(n)):<br> chunks.append(" " * (n -i) + "for x%s in s%s:" % (i, i))<br> chunks.append(" " * n + " yield (" + ', '.join('x%s' % i for i in range(n)) + ')')
<br> code = '\n'.join(chunks)<br> exec code<br> return f(*seqs)<br> <br> a = "abcde"*10<br> b = range(99)<br> c = [x**2 for x in range(33)]<br> seqs = [a, b, c]
<br> <br> if __name__ == "__main__":<br> assert list(count_combinations(seqs)) == list(cg_combinations(seqs))<br> <br> import timeit<br> test = timeit.Timer('list(count_combinations(seqs))',
<br> 'from __main__ import count_combinations, seqs')<br> t1 = test.timeit(number=10)<br> test = timeit.Timer('list(cg_combinations(seqs))',<br> 'from __main__ import cg_combinations, seqs')
<br> t2 = test.timeit(number=10)<br> print t1, t2