Counting without zeroes Below is a python script that generates the sequence ['a', 'b' .. 'z', 'aa', 'ab' .. 'az', 'ba', 'bb' .. 'zz', 'aaa', 'aab', ..]

This is essentially counting in base 27, replacing every digit with the n-th letter of the alphabet, but skipping any number that would have a '0'.

import string


def gen_labels():
    i = 0
    n = len(string.ascii_lowercase) + 1
    while True:
        i += 1
        j = i
        result = ''
        while True:
            c = j % n
            if not c:
                break
            result = string.ascii_lowercase[c-1] + result
            if j &lt; n:
                break
            j = j // n
        if c:
            yield result


print(list(zip(gen_labels(), range(1000))))


However, the code seems overly long to me for generating such a straightforward series and it's doing a lot of work to break down values that would have a '0' in them in base 27. 

What is a more efficient way of generating the exact same (infinite) series?

Note that I'm not worried that much about speed, but mainly about the brevity / simplicity of the algorithm - it seems overly complicated, but I don't really see my way to an efficient realisation.
Well, what you want is just a product of the alphabet, with increasing numbers of elements. You can use itertools.product for this:

from itertools import product, count
from string import ascii_lowercase

def generate_labels():
    """Yields labels of the following form:
       a, b, ..., z, aa, ab, ..., zz, aaa, aab, ..., zzz, ...
    """
    for n in count(start=1):
        yield from map("".join, product(*[ascii_lowercase]*n))


Here is what it outputs:

from itertools import islice

print(list(islice(generate_labels(), 1000)))
# ['a', 'b', ..., 'z', 'aa', 'ab', ..., 'az', 'ba', 'bb', ..., 'bz', ..., 'za', ..., 'zz', 'aaa', 'aab', ..., 'all']


This has the slight disadvantage that the list being passed to product gets larger every iteration. But already with \$n=5\$ you can generate \$\sum_{k=1}^n 26^k = 12,356,630\$ labels, and the list is only about sys.getsizeof([ascii_lowercase]*5) + sys.getsizeof(ascii_lowercase) * 5 = 479 bytes large, so in practice this should not be a problem.



I also made the name a bit longer (and clearer IMO) and added a docstring to briefly describe what the function is doing.