Automatic recognition?

I have a method in which I need to pass a constantly increasing integer to another function.

I can do it like this:

def foo(i): print i def bar(): class Incrementer(object): def __init__(self, start=0): self.i = start def __get__(self): j = self.i self.i += 1 return j number = Incrementer() foo(number) foo(number) foo(number) 

which correctly outputs 0 1 2 ... but I feel like I'm missing a much simpler (or inline) way to do this?

+7
source share
2 answers

Try itertools.count() - it does exactly what you need:

 >>> c = itertools.count() >>> next(c) 0 >>> next(c) 1 >>> next(c) 2 
+14
source

In general, if you need to save a state between one function call and the next, then you want either an object (your solution) or a generator. In some cases, one will be simpler than the other, but there is nothing wrong with how you did it, in principle (although you seem to have some implementation problems).

Sven's suggestion, itertools.count() , is a generator. Its implementation looks something like this:

 def count(): i = 0 while True: yield i i += 1 

Now, if you want it to be called as a function, instead of doing next(c) , you could define a wrapper that would do it like this:

  def count(c=itertools.count()): return next(c) 

Or the inevitable single-line lambda:

 count = lambda c=itertools.count(): next(c) 

Then count() returns the next integer each time it is called.

Of course, if you want to create any number of called functions, each with its own counter, you can write a factory for this:

 def counter(): return lambda c=itertools.count(): next(c) 

Then this:

 c = counter() print c() # 0 print c() # 1 # etc 

It seems to me simpler than an object, but not by much. If your state or logic was more complex, encapsulating an object could win.

+7
source

All Articles