为什么chunk不是python标准lib的一部分?

时间:2013-05-01 05:05:48

标签: python

阅读How do you split a list into evenly sized chunks?后,一直看到https://code.djangoproject.com/ticket/18972发生此类错误。

为什么不在itertools中使用chunk函数?

编辑: 来自http://docs.python.org/2/library/itertools.html#recipesgrouperchunks

的行为不同

示例:

chunks([1, 2, 3, 4, 5], 3)
# Should return [[1, 2, 3], [4, 5]] or the iterator equivalent.

2 个答案:

答案 0 :(得分:4)

这里发布这样的问题不是将这样的东西添加到Python中的方法。您应该尝试使用Python邮件列表。

我使用您请求的语义为您实现了chunks()。正确处理最后一个块是有点棘手,但否则这很容易。如果它被添加到itertools,它将被写入C,因此它会更快。

在Python 2.6,Python 2.7和Python 3.2中测试并使用。

import itertools as it
import sys

# use lazy xrange on 2.x; on 3.x plain "range" is always lazy
if sys.version_info[0] < 3:
    _range = xrange
else:
    _range = range

def chunks(iterable, n):
    """
    Yield up lists of n elements, taken from iterable.
    If length of iterable is not evenly divisible by n, the last list will be short.
    """
    if n < 1:
        raise ValueError("n must be >= 1")

    itr = iter(iterable)
    try:
        while True:
            lst = []
            for _ in _range(n):
                lst.append(next(itr))
            if not lst:
                break
            yield lst
    except StopIteration:
        # Only yield up a partial chunk if it is not zero length.
        if lst:
            yield lst

print(list(chunks([1, 2, 3, 4, 5, 6], 3)))  # prints: [[1, 2, 3], [4, 5, 6]]
print(list(chunks([1, 2, 3, 4, 5], 3))) # prints: [[1, 2, 3], [4, 5]]
print(list(chunks([], 3))) # prints: []
print(list(chunks([1, 2], 0))) # raises ValueError exception

编辑:

上述解决方案效率低下有点困扰我。我很确定使用itertools.islice()必须有一个更简单的解决方案,所以我想出来了。我更喜欢这个。

def chunks(iterable, n):
    """
    Yield up lists of n elements, taken from iterable.
    If length of iterable is not evenly divisible by n, the last list will be short.
    """
    if n < 1:
        raise ValueError("n must be >= 1")

    itr = iter(iterable)

    while True:
        lst = list(it.islice(itr, n))
        if not lst:
            break
        yield lst

答案 1 :(得分:2)

它不在itertools中,但它在itertools的页面上被提到作为食谱:

http://docs.python.org/2/library/itertools.html#recipes

def grouper(n, iterable, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

您也可以问为什么所有其他食谱都不包含在itertools中:)