def ordered_product(ranges, order): """Iterates through ranges in the order specified in order, but each yeild returns in the original order of the ranges""" order_inv = zip(*sorted(zip(order, sorted(order))))[1] for prod in product(*(ranges[o] for o in order)): yield tuple(prod[o] for o in order_inv) ranges = [[0,1], ['a','b','c'], ['w', 'x', 'y', 'z']] print list(ordered_product(ranges, [0, 1, 2])) print list(ordered_product(ranges, [2, 0, 1])) # this is the input with problems