(这个问题是关系到这一个和这一个,但这些都是预先行走发电机,而这正是我想避免的)
我想将生成器拆分为多个块。要求是:
不要填充数据块:如果剩余元素的数量小于数据块大小,则最后一个数据块必须较小。
不要事先遍历生成器:计算元素是昂贵的,并且只能由使用函数来完成,而不是由分块器来完成
这当然意味着:不要在内存中累积(无列表)
我尝试了以下代码:
def head(iterable, max=10):
for cnt, el in enumerate(iterable):
yield el
if cnt >= max:
break
def chunks(iterable, size=10):
i = iter(iterable)
while True:
yield head(i, size)
# Sample generator: the real data is much more complex, and expensive to compute
els = xrange(7)
for n, chunk in enumerate(chunks(els, 3)):
for el in chunk:
print 'Chunk %3d, value %d' % (n, el)
这以某种方式起作用:
Chunk 0, value 0
Chunk 0, value 1
Chunk 0, value 2
Chunk 1, value 3
Chunk 1, value 4
Chunk 1, value 5
Chunk 2, value 6
^CTraceback (most recent call last):
File "xxxx.py", line 15, in <module>
for el in chunk:
File "xxxx.py", line 2, in head
for cnt, el in enumerate(iterable):
KeyboardInterrupt
Buuuut ...它永远不会停止(我必须按下^C)while True。每当生成器被耗尽时,我都想停止该循环,但是我不知道如何检测到这种情况。我试图提出一个异常:
class NoMoreData(Exception):
pass
def head(iterable, max=10):
for cnt, el in enumerate(iterable):
yield el
if cnt >= max:
break
if cnt == 0 : raise NoMoreData()
def chunks(iterable, size=10):
i = iter(iterable)
while True:
try:
yield head(i, size)
except NoMoreData:
break
# Sample generator: the real data is much more complex, and expensive to compute
els = xrange(7)
for n, chunk in enumerate(chunks(els, 2)):
for el in chunk:
print 'Chunk %3d, value %d' % (n, el)
但是然后仅在使用方的上下文中引发异常,这不是我想要的(我想保持使用方代码干净)
Chunk 0, value 0
Chunk 0, value 1
Chunk 0, value 2
Chunk 1, value 3
Chunk 1, value 4
Chunk 1, value 5
Chunk 2, value 6
Traceback (most recent call last):
File "xxxx.py", line 22, in <module>
for el in chunk:
File "xxxx.py", line 9, in head
if cnt == 0 : raise NoMoreData
__main__.NoMoreData()
我如何在chunks不走动的情况下检测发电机是否在功能中耗尽?
呼啦一阵风
30秒到达战场
相关分类