I know you can use c = cycle(['a', 'b', 'c'])
to cycle between the elements using c.next()
, but is there away to get the iterator's current element?
for example if c.next()
returned 'c'
, it means that iterator was at 'b'
before. Is there a way I can get 'b'
without using next()
?
This module implements a number of iterator building blocks inspired by constructs from APL, Haskell, and SML. Each has been recast in a form suitable for Python.
islice() functionThis iterator selectively prints the values mentioned in its iterable container passed as an argument. Syntax: islice(iterable, start, stop, step)
While this is a perfectly fine approach, it is important to remember that utilizing the itertools iterators means using iterators that are Pythonic implementations of iterators elsewhere. That being said, the iterators from itertools are often significantly faster than regular iteration from a standard Python for loop.
chain() function It is a function that takes a series of iterables and returns one iterable. It groups all the iterables together and produces a single iterable as output.
Iterators/generators don't have any way to get the current value. You should either keep a reference to it or create some wrapper that holds onto it for you.
Note: This only works if there are no repeated elements.
Whether this is a serious practical limitation depends on each one's use.
In my case, most of the itertools.cycle
I have worked with fall under this category.
One can actually get the current state of a cycle
with a helper function, and other info as well.
It actually uses next
, but this is transparent to the caller.
import itertools
def get_cycle_props(cycle) :
"""Get the properties (elements, length, current state) of a cycle, without advancing it"""
# Get the current state
partial = []
n = 0
g = next(cycle)
while ( g not in partial ) :
partial.append(g)
g = next(cycle)
n += 1
# Cycle until the "current" (now previous) state
for i in range(n-1) :
g = next(cycle)
return (partial, n, partial[0])
def get_cycle_list(cycle) :
"""Get the elements of a cycle, without advancing it"""
return get_cycle_props(cycle)[0]
def get_cycle_state(cycle) :
"""Get the current state of a cycle, without advancing it"""
return get_cycle_props(cycle)[2]
def get_cycle_len(cycle) :
"""Get the length of a cycle, without advancing it"""
return get_cycle_props(cycle)[1]
# initialize list
test_list = [3, 4, 5, 7, 1]
c = itertools.cycle(test_list)
print('cycle state =', get_cycle_state(c))
print('cycle length =', get_cycle_len(c))
print('cycle list =', get_cycle_list(c))
next(c)
print('cycle state =', get_cycle_state(c))
print('cycle length =', get_cycle_len(c))
print('cycle list =', get_cycle_list(c))
produces the following output
cycle state = 3
cycle length = 5
cycle list = [3, 4, 5, 7, 1]
cycle state = 4
cycle length = 5
cycle list = [4, 5, 7, 1, 3]
This can actually be taken advantage of to "rewind" a cycle, with the function
def shift_cycle(cycle, npos=0) :
"""Shift a cycle, a given number of positions (can be negative)."""
(cycle_list, nelem, curr_state) = get_cycle_props(cycle)
for i in range(nelem+npos) :
g = next(cycle)
return
Try
shift_cycle(c, -2)
print('cycle state =', get_cycle_state(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