Efficient solution to Project Euler 14 (Longest Collatz sequence) This is an iterative review. I asked for reviews on a Collatz sequence generator here. I tried to address all of the suggestions that were made.

I've added a new function get_longest_collatz(n), which can be used to solve Project Euler problem 14 (the question states: which number under a million has the longest Collatz sequence?)

The solution makes use of memoization.

def collatz(n):
    """
    Generator for collatz sequence beginning with n.
    n must be 0, 1, 2 ...

    &gt;&gt;&gt; list(collatz(1))
    [1]

    &gt;&gt;&gt; list(collatz(10))
    [10, 5, 16, 8, 4, 2, 1]
    """
    yield n
    while n &gt; 1:
        n = n // 2 if n % 2 == 0 else 3 * n + 1
        yield n


def get_longest_collatz(n):
    """
    Returns the number less than n with the longest collatz sequence.

    &gt;&gt;&gt; get_longest_collatz(1000)
    871
    """
    lengths = {} # Keys are natural numbers, values are lengths of collatz sequence
    for i in range(n):
        for count, x in enumerate(collatz(i)):
            if x in lengths:
                # The sequence length for x has already been found
                lengths[i] = count + lengths[x] # Add onto previously found sequence length
                break
        else:
            lengths[i] = len(list(collatz(i))) # Store full length of collatz sequence
    return max(lengths, key=lengths.get) # Key of memo with largest value
n must be 0, 1, 2 ...


Should be:

n must be 1, 2, 3 ...


Or say that:

n must be a positive integer.


Your code doesn't give an infinite loop, but it doesn't make sense really that you return [0] for your function. If you "allowed" 0 the collatz funciton would return an infinite list of 0s. (Why?)