The itertools.count
counter in Python (2.7.9) is very handy for thread-safe counting. How can I get the current value of the counter though?
The counter increments and returns the last value every time you call next()
:
import itertools
x = itertools.count()
print x.next() # 0
print x.next() # 1
print x.next() # 2
So far, so good.
I can't find a way to get the current value of the counter without calling next()
, which would have the undesirable side-effect of increasing the counter, or using the repr()
function.
Following on from the above:
print repr(x) # "count(3)"
So you could parse the output of repr()
. Something like
current_value = int(repr(x)[6:-1])
would do the trick, but is really ugly.
Is there a way to get the current value of the counter more directly?
itertools. count() makes an iterator that returns values that counts up or down infinitely. itertools.count() — Functions creating iterators for efficient looping — Python 3.9.7 documentation.
To count objects, you typically use a counter, which is an integer variable with an initial value of zero. Then you increment the counter to reflect the number of times a given object appears in the input data source. When you're counting the occurrences of a single object, you can use a single counter.
In Python, you can count the total number of elements in a list or tuple with the built-in function len() and the number of occurrences of an element with the count() method.
The cycle() function accepts an iterable and generates an iterator, which contains all of the iterable's elements. In addition to these elements, it contains a copy of each element.
Another hack to get next value without advancing iterator is to abuse copy protocol:
>>> c = itertools.count()
>>> c.__reduce__()[1][0]
0
>>> next(c)
0
>>> c.__reduce__()[1][0]
1
Or just take it from object copy:
>>> from copy import copy
>>> next(copy(c))
1
Use the source, Luke!
According to module implementation, it's not possible.
typedef struct {
PyObject_HEAD
Py_ssize_t cnt;
PyObject *long_cnt;
PyObject *long_step;
} countobject;
Current state is stored in cnt
and long_cnt
members, and neither of them is exposed in object API. Only place where it may be retrieved is object __repr__
, as you suggested.
Note that while parsing string you have to consider a non-singular increment case. repr(itertools.count(123, 4))
is equal to 'count(123, 4)'
- logic suggested by you in question would fail in that case.
According to the documentation there is no way to access the current value of the function. itertools.count()
is a generator method from the itertools
module. As such, it is common practice to just simply assign the value of a generator's current value to a variable.
Simply store the the result of the next call:
current_value = x.next()
or ( Built-in python method for Python version ≥ 2.6 )
current_value = next(x)
You could make a wrapper function, or a utility decorator class if you would like some added syntactic sugar, but assignment is standard.
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