Search code examples
pythongeneratoriterable

Length of generator output


Python provides a nice method for getting length of an eager iterable, len(x) that is. But I couldn't find anything similar for lazy iterables represented by generator comprehensions and functions. Of course, it is not hard to write something like:

def iterlen(x):
  n = 0
  try:
    while True:
      next(x)
      n += 1
  except StopIteration: pass
  return n

But I can't get rid of a feeling that I'm reimplementing a bicycle.

(While I was typing the function, a thought struck my mind: maybe there really is no such function, because it "destroys" its argument. Not an issue for my case, though).

P.S.: concerning the first answers - yes, something like len(list(x)) would work too, but that drastically increases the usage of memory.

P.P.S.: re-checked... Disregard the P.S., seems I made a mistake while trying that, it works fine. Sorry for the trouble.


Solution

  • There isn't one because you can't do it in the general case - what if you have a lazy infinite generator? For example:

    def fib():
        a, b = 0, 1
        while True:
            a, b = b, a + b
            yield a
    

    This never terminates but will generate the Fibonacci numbers. You can get as many Fibonacci numbers as you want by calling next().

    If you really need to know the number of items there are, then you can't iterate through them linearly one time anyway, so just use a different data structure such as a regular list.