石斑鱼食谱但最后回归" group"即使长度不均匀

时间:2016-12-26 15:45:36

标签: python itertools

我正在追踪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元素,则它不会返回最后一个组。我遇到过几种情况,我想要最后一组是否与所有其他组的大小相同。我也不想添加任何填充。我该怎么做呢?

2 个答案:

答案 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',)]