Skip to content

Commit ed7c93f

Browse files
committed
[GR-13493] Add itertools.cycle
PullRequest: graalpython/374
2 parents 0ff7d28 + 96224fd commit ed7c93f

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_iterator.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,15 @@ def test_itertools_zip_longest():
129129
x = [1,2,3]
130130
y = [4,5,6,7]
131131
assert list(zip_longest(x,y)) == [(1, 4), (2, 5), (3, 6), (None, 7)], list(zip_longest(x,y))
132+
133+
134+
def test_itertools_cycle():
135+
from itertools import cycle
136+
x = [1,2,3]
137+
r = []
138+
for i in cycle(x):
139+
r.append(i)
140+
if len(r) > 10:
141+
break
142+
assert r == [1,2,3,1,2,3,1,2,3,1,2], r
143+
assert [x for x in cycle([])] == []

graalpython/lib-graalpython/itertools.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,3 +648,52 @@ def __new__(subtype, iter1, *args, fillvalue=None):
648648
self.active = len(args) + 1
649649
self.iterators = [iter(iter1)] + [iter(arg) for arg in args]
650650
return self
651+
652+
653+
class cycle():
654+
"""
655+
Make an iterator returning elements from the iterable and
656+
saving a copy of each. When the iterable is exhausted, return
657+
elements from the saved copy. Repeats indefinitely.
658+
659+
Equivalent to :
660+
661+
def cycle(iterable):
662+
saved = []
663+
for element in iterable:
664+
yield element
665+
saved.append(element)
666+
while saved:
667+
for element in saved:
668+
yield element
669+
"""
670+
671+
def __init__(self, iterable):
672+
self.saved = []
673+
self.iterable = iter(iterable)
674+
self.index = 0
675+
676+
def __iter__(self):
677+
return self
678+
679+
def __next__(self):
680+
if self.index > 0:
681+
if not self.saved:
682+
raise StopIteration
683+
if len(self.saved) > self.index:
684+
obj = self.saved[self.index]
685+
self.index += 1
686+
else:
687+
obj = self.saved[0]
688+
self.index = 1
689+
else:
690+
try:
691+
obj = next(self.iterable)
692+
except StopIteration:
693+
if not self.saved:
694+
raise
695+
obj = self.saved[0]
696+
self.index = 1
697+
else:
698+
self.saved.append(obj)
699+
return obj

0 commit comments

Comments
 (0)