我正在追踪grouper()
的{{1}}食谱:
itertools
此版本使用给定值填充最后一个组。如果我删除了def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
,那么如果它具有小于fillvalue
元素,则它不会返回最后一个组。我遇到过几种情况,我想要最后一组是否与所有其他组的大小相同。我也不想添加任何填充。我该怎么做呢?
答案 0 :(得分:1)
我通常使用islice
:
from itertools import islice
def grouper(iterable, n):
iterator = iter(iterable)
group = tuple(islice(iterator, n))
while group:
yield group
group = tuple(islice(iterator, n))
如果您愿意,以下只是逻辑上的细微变化,但它的工作方式相同:
def grouper(iterable, n):
iterator = iter(iterable)
while True:
group = tuple(islice(iterator, n))
if not group:
return
yield group
这里还有其他变种。例如,如果你想要一个完全懒惰的版本:
from itertools import groupby
def grouper(iterable, n):
iterator = enumerate(iterable)
for unused_group_number, idx_items in groupby(iterator, lambda t: t[0] // n):
yield (item for unused_idx, item in idx_items)
这可能不如islice
那么高,因为它会回调到python,但它完全是懒惰的(并且是安全的)。例如它会在组上生成迭代器,并处理调用者不会消耗组迭代器中的每个元素的情况。
答案 1 :(得分:1)
您可以在循环中使用islice()
来读取块中的元素:
from itertools import islice
def grouper(iterable, n):
it = iter(iterable)
group = tuple(islice(it, n))
while group:
yield group
group = tuple(islice(it, n))
print(list(grouper('ABCDEFG', 3))) # [('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)]