0

There are multiple questions here asking about infinite range that all recommend itertools.count. However, range has one ability that count does not—it can be reused.

a = range(100)

# Prints 0 1 2 3
for i in a:
    print(i)
    if i >= 3:
        break

# Prints 0 1 2 3
for i in a:
    print(i)
    if i >= 3:
        break

from itertools import count
b = count(0)

# Prints 0 1 2 3
for i in b:
    print(i)
    if i >= 3:
        break

# Prints 4, does not use a fresh count(0)
for i in b:
    print(i)
    if i >= 3:
        break

Is there a way to reuse itertools.count or otherwise get a reusuable/restarting infinite iterable?

drhagen
  • 8,331
  • 8
  • 53
  • 82

1 Answers1

2

The fundamental problem is that range is an Iterable and count is an Iterator. Iterators are objects that have a __next__ method and can be stepped through only once, while Iterables have a __iter__ method, which can be called multiple times to return a fresh Iterator each time.

One solution is to simply create your own Iterable version of count which simply returns itertools.count whenever its __iter__ method is called.

from itertools import count

class Count:
    def __init__(self, start=0):
        self.start = start

    def __iter__(self):
        return count(self.start)
drhagen
  • 8,331
  • 8
  • 53
  • 82