How can I using yield list element infinitely
Question:
I have directory list and this element should be returned at one at a time
so I coded like below:
def gen():
list = ["dir_1", "dir_2", ..., "dir_n"]
for i in list:
yield i
But, I wanna get directory over and over again, e.g dir_1
, dir_2
, … ,dir_n
, dir_1
, dir_2
… like that.
How should I do?
Answers:
You can use itertools.cycle
for exactly what you describe:
from itertools import cycle
def gen():
lst = ["dir_1", "dir_2", "dir_n"]
for i in cycle(lst):
yield i
so that:
i = gen()
for _ in range(5):
print(next(i))
outputs:
dir_1
dir_2
dir_n
dir_1
dir_2
This is a solution by the means of While
loop.
def gen():
while True:
mylist = ["dir_1", "dir_2"]
for i in mylist:
yield i
You can use cycle, no need for another generator just call cycle on an iterator and it will cycle forever
from itertools import cycle
for dir in cycle(["dir_1", "dir_2", "dir_n"]):
do stuff ...
if some_reason:
break
The following solution should be faster and more efficient:
def gen(lst):
yield from lst
yield from gen(lst)
Usage:
>>> g = gen(['a','b','c'])
>>> for x in g:
>>> do something...
>>> if some_reason:
>>> break
>>> [next(g) for _ in range(7)]
['a', 'b', 'c', 'a', 'b', 'c', 'a']
Alternatively, if you want a limit to the cycling generator, you can use the following version which allows you to set (optionally) the total length of the output sequence:
def gen(lst,limit=None):
if type(limit) == int:
g = gen(lst)
for _ in range(limit):
yield next(g)
return
yield from lst
yield from gen(lst,limit)
Usage:
>>> g = gen(['a','b','c'], limit=7))
>>> for x in g:
>>> do something (for 7 times)...
>>> list(g)
['a', 'b', 'c', 'a', 'b', 'c', 'a']
N.B. If the limit you set is greater than Python recursion capabilities (usually 1000 recursions) you can improve such capabilities through the following code:
>>> import sys
>>> sys.setrecursionlimit(some_greater_limit)
I have directory list and this element should be returned at one at a time
so I coded like below:
def gen():
list = ["dir_1", "dir_2", ..., "dir_n"]
for i in list:
yield i
But, I wanna get directory over and over again, e.g dir_1
, dir_2
, … ,dir_n
, dir_1
, dir_2
… like that.
How should I do?
You can use itertools.cycle
for exactly what you describe:
from itertools import cycle
def gen():
lst = ["dir_1", "dir_2", "dir_n"]
for i in cycle(lst):
yield i
so that:
i = gen()
for _ in range(5):
print(next(i))
outputs:
dir_1
dir_2
dir_n
dir_1
dir_2
This is a solution by the means of While
loop.
def gen():
while True:
mylist = ["dir_1", "dir_2"]
for i in mylist:
yield i
You can use cycle, no need for another generator just call cycle on an iterator and it will cycle forever
from itertools import cycle
for dir in cycle(["dir_1", "dir_2", "dir_n"]):
do stuff ...
if some_reason:
break
The following solution should be faster and more efficient:
def gen(lst):
yield from lst
yield from gen(lst)
Usage:
>>> g = gen(['a','b','c'])
>>> for x in g:
>>> do something...
>>> if some_reason:
>>> break
>>> [next(g) for _ in range(7)]
['a', 'b', 'c', 'a', 'b', 'c', 'a']
Alternatively, if you want a limit to the cycling generator, you can use the following version which allows you to set (optionally) the total length of the output sequence:
def gen(lst,limit=None):
if type(limit) == int:
g = gen(lst)
for _ in range(limit):
yield next(g)
return
yield from lst
yield from gen(lst,limit)
Usage:
>>> g = gen(['a','b','c'], limit=7))
>>> for x in g:
>>> do something (for 7 times)...
>>> list(g)
['a', 'b', 'c', 'a', 'b', 'c', 'a']
N.B. If the limit you set is greater than Python recursion capabilities (usually 1000 recursions) you can improve such capabilities through the following code:
>>> import sys
>>> sys.setrecursionlimit(some_greater_limit)