40

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?

1
  • 1
    Note that if your test iterable is empty and doesn't produce anything -- as shown and in most or all of the answers -- your test won't exercise any of the code in the for loop.
    – martineau
    Commented May 16, 2012 at 17:08

6 Answers 6

43

Yes, there is:

return iter([])
3
  • 1
    that's nice but I got: F999 warning
    – lang2
    Commented Sep 5, 2017 at 6:05
  • 4
    You may want to consider the pythonic yield from () instead.
    – aluriak
    Commented Feb 5, 2020 at 13:38
  • [] creates a new object every time the expression is evaluated. It is better to use empty tuple instead (). Empty tuple can even be a singleton (not guaranteed) - every empty tuple refers to the same object. Commented Jun 4, 2022 at 21:18
30

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.

3
  • 7
    This is it. While answers like lambda: iter(()) satisfy man's instinctual drive for cleverness, they're also unreadable and fail to produce an actual generator. In particular, isinstance(iter(()), types.GeneratorType) == False. As the relative success of mypy shows, types sometimes do matter. Always yield from, Python 3 people. Commented Aug 8, 2017 at 6:20
  • Am I right in thinking that () has no meaning in Python? It's not an empty tuple, I know that much. Would this be better written as yield from []?
    – LondonRob
    Commented Apr 24 at 17:40
  • () means empty tuple. Proof : assert isinstance((), tuple)
    – aluriak
    Commented Apr 24 at 18:36
14

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

my_iterable = lambda: iter(())
11

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__).

4
  • Accepted because of reference to Python standard library. Commented May 21, 2012 at 7:10
  • 1
    That makes me curious. Why is str iterable? Commented May 14, 2020 at 17:45
  • @DanielWalker You can iterate over the characters in the string.
    – MEMark
    Commented Oct 30, 2022 at 20:11
  • @MEMark, yes, but you can't iterate over str itself. Commented Nov 2, 2022 at 14:44
2
def do_yield():
    return
    yield None

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

0
0

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.