def lex_gen(bounds):
    elem = [0] * len(bounds)
while True:
    yield elem
i = 0
while elem[i] == bounds[i] - 1:
    elem[i] = 0
i += 1
if i == len(bounds):
    raise StopIteration
elem[i] += 1

def cart_product(lists):
    bounds = [len(lst) for lst in lists]
for elem in lex_gen(bounds):
    yield [lists[i][elem[i]] for i in range(len(lists))]
for k in cart_product([['1', '2'], ['x', 'y'], ['a', 'b', 'c']]):
    pass
Python cartesian product of n lists with n unknown at coding time