from itertools import islice

def scale(s, m):
    return (x*m for x in s)

def merge(s1, s2):
    x1, x2 = next(s1), next(s2)
    if x1 < x2:
        x = x1
        it = iter(merge(s1, s2))
    elif x1 > x2:
        x = x2
        it = iter(merge(s1, s2))
    else:
        x = x1
        it = iter(merge(s1, s2))
    yield x
    while True: yield next(it)

def integers():
    n = 0
    while True:
        n += 1
        yield n

m2 = scale(integers(), 2)
m3 = scale(integers(), 3)
m5 = scale(integers(), 5)

m23 = merge(m2, m3)

hamming_numbers = merge(m23, m5)

print( list( islice(m23,0,10)))

print( list( islice(m2,0,10)))
print( list( islice(m3,0,10)))
print( list( islice(m3,0,10)))
print( list( islice(m5,0,10)))
print( list( islice(m5,0,10)))


print( list( islice(hamming_numbers,0,10)))
print( list( islice(hamming_numbers,0,10)))
