我必须忽略显而易见的事情,但我不能为我的生活弄清楚为什么这个yield语句不会持续给我一个比前一个晚15分钟的新日期时间值。 gettime函数的行为更像是“返回”而不是“yield”的函数。
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.
答案 0 :(得分:15)
这是因为你每次都在调用发生器,重新启动它。
这是一个固定版本:
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()
这让我:
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.
要记住的一件重要事情是yield
实际上返回生成器的函数,就像我们查看dates
对象时所看到的那样:
>>> dates
<generator object gettime at 0x02A05710>
这是您可以反复调用next()
以获取下一个值的内容。每次执行循环时,您都创建了一个全新生成器并从中获取下一个(在本例中为第一个)值。
答案 1 :(得分:3)
丹尼尔已经指出你每次通过循环创建一个新的生成器。循环生成器或让另一个生成器使用它比通常每次显式调用next()
更常见。
以下是如何循环生成器的islice()。
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
如果您愿意,也可以将其简化为生成器表达式
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
答案 2 :(得分:0)
使用print_function:
print(*[i[0] for i in zip(gettime(nextdate), range(25))], sep='\n')
但你可能只想要清单。