Python's exit statement doesn't seem to continue where it left off

I must overlook the obvious, but because of my life I can’t understand why this yield statement does not give me a new datetime value, which is 15 minutes later than the previous one. The gettime function behaves more like a function that "returns" rather than "gives."

import datetime #function that continually adds 15 minutes to a datetime object def gettime(caldate): while True: yield caldate caldate += datetime.timedelta(minutes=15) #initialize a datetime object nextdate = datetime.datetime(2011, 8, 22, 11,0,0,0) #call gettime function 25 times. for i in range(0,25): print gettime(nextdate).next() #output feels like it should be a series of incrementing datetime values 15 minutes apart. #in actuality, the same result namely: #2011-08-22 11:00:00 #happens 25 times. 
+4
source share
3 answers

This is because you call the generator each time, starting it again.

Here is the fixed version:

 dates = gettime(nextdate) for i in range(0, 25): print dates.next() # note that you're not initializing it each time here # just calling next() 

This gives me:

 2011-08-22 11:00:00 2011-08-22 11:15:00 2011-08-22 11:30:00 2011-08-22 11:45:00 ...etc. 

It is important to remember that the yield function actually returns a generator , as you can see when we look at my dates object:

 >>> dates <generator object gettime at 0x02A05710> 

This is what you can call next() on repeatedly to get the next value. Each time you execute your cycle, you create a completely new generator and get the following (in this case, the first) value from it.

+15
source

Daniel already indicated that each time you create a new generator through your cycle. Most often, quoting a generator or using a different generator than explicitly calling next() each time.

Here's how you could iterate over the exlice () of your generator.

 from itertools import islice import datetime #generator that continually adds 15 minutes to a datetime object def gettime(caldate): while True: yield caldate caldate += datetime.timedelta(minutes=15) #initialize a datetime object nextdate = datetime.datetime(2011, 8, 22, 11,0,0,0) #call gettime function 25 times. for the_date in islice(gettime(nextdate),0,25): print the_date 

You can also simplify this generator expression if you want

 from itertools import islice, count import datetime #initialize a datetime object nextdate = datetime.datetime(2011, 8, 22, 11,0,0,0) #generator expression that continually adds 15 minutes to a datetime object gettime = (nextdate+datetime.timedelta(minutes=15*i) for i in count()) #call gettime function 25 times. for the_date in islice(gettime,0,25): print the_date 
+3
source

Using print_function:

 print(*[i[0] for i in zip(gettime(nextdate), range(25))], sep='\n') 

But you can only have a list.

0
source

All Articles