Jo Chan
Jo Chan

Reputation: 11

How to iterate a list over and over again?

I'm trying to write a that will return a sequence of month names with Python.

For example, if I put:

gen = next_month('October')
lst = [next(gen) for i in range(15)]
print (lst)

I should get:

['November', 'December', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',  'September', 'October', 'November', 'December', 'January'])

But I get index out of range error with the following codes:

month_names = ['January', 'February', 'March', 'April', 'May', 'June',
                'July', 'August', 'September', 'October', 'November', 'December']

def next_month(name: str) -> str:
    "Return a stream of the following months"
    global month_names
    month_index = month_names.index(name)
    while True:
            yield (month_names[month_index])
            month_index = month_index + 1

Just not sure how to fix it. Thanks in advance for any guidance!

Upvotes: 1

Views: 918

Answers (2)

Jab
Jab

Reputation: 27485

Probably not great for a homework answer but without hard coding the months you can use itertools.count and datetime.datetime:

def next_month(name):
    date = datetime.strptime(name, '%B')
    for m in count(date.month):
        date = date.replace(month=1+(m%12))
        yield date.strftime('%B')

gen = next_month('October')
print([next(gen) for i in range(15)])

This prints:

['November', 'December', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', 'January']

This could also be done using a while loop although using count is a a shortcut

Upvotes: 0

Christian Sloper
Christian Sloper

Reputation: 7510

itertools have a function cycle, that loops an iterator:

from itertools import cycle

month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

for month in cycle(month_names):
    print(month)

Homework edition:

def gen_cycle(l):
    cnt = 0
    while True:
        yield l[cnt]
        cnt = (cnt+1)%len(l)

Upvotes: 2

Related Questions