How do I write a function that simply returns incrementing numbers on each call?
print counter() # 0
print counter() # 1
print counter() # 2
print counter() # 3
etc
For clarity, I'm not looking for a generator (although the answer would probably use it). The function should return an integer, not an iterable object. I'm also NOT looking for a solution involving global or otherwise shared variables (classes, function attribute etc).
See here http://www.valuedlessons.com/2008/01/monads-in-python-with-nice-syntax.html for some useful insights about the matter.
You don't need to implement that function -- it already exists:
counter = itertools.count().next
or in Python 3.x
counter = itertools.count().__next__
More generally, if you want a callable that has additional state, there are several solutions:
A class:
class Counter(object):
def __init__(self, start=0):
self.count = 0
def __call__(self):
val = self.count
self.count += 1
return val
A mutable default argument:
def counter(_count=[0]):
val = _count[0]
_count[0] += 1
return val
A closure:
def make_counter(start=0):
count = [start]
def counter():
val = count[0]
count[0] += 1
return val
return counter
In Python 3.x, you wouldn't need the above hack using a list any more, since you could use a nonlocal declaration:
def make_counter(start=0):
count = start
def counter():
nonlocal count
val = count
count += 1
return val
return counter
Function arguments:
def counter():
val = counter.count
counter.count += 1
return val
counter.count = 0
A generator:
def count(start=0):
while True:
yield start
start += 1
counter = count().next ## or .__next__ in Python 3.x
Of course all these solution have to store the current count somewhere.
In short,
from itertools import count
counter = lambda c=count(): next(c)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With