I was playing around with iterables and more specifically the yield operator in Python. While using test driven development to start writing a new iterable, I wondered what is the shortest code that could make this simple test for an iterable to pass:

def test():
    for x in my_iterable():
        pass

The shortest version I could think of was:

def my_iterable():
    for i in []:
        yield i

Is it possible to write a simpler, shorter or more beautiful (pythonic) version?

Yes, there is:

return iter([])

Another solution, in Python 3, is to use the new yield from syntax:

def empty_gen():
    yield from ()

Which is readable, and keep empty_gen as a generator.

You can use the lambda and iter functions to create an empty iterable in Python.

my_iterable = lambda: iter(())

How about

my_iterable = str

this passes your test.

To speak seriously, Iterable in the collections module provides:

def __iter__(self):
    while False:
        yield None

This can be considered “most pythonic” because this is what python itself uses.

Note that technically all answers so far provide iterators (__iter__ + next), not iterables (just __iter__).

def do_yield():
    return
    yield None

if usage of yield is important for you, one of the other answers otherwise.

Another answer, as I provide a completely new solution with a different approach.

In one of by libraries, I have an EmptyIterator such as

class EmptyIter(object):
    __name__ = 'EmptyIter'
    """Iterable which is False and empty"""
    def __len__(self): return 0
    def next(self): raise StopIteration # even that is redundant
    def __getitem__(self, index): raise IndexError

It is an alternative approach which uses the following properties:

  • alternative iteration via the sequence protocol (see here)
  • alternative “falseness” protocol as described here.