阅读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#recipes的grouper
与chunks
示例:
chunks([1, 2, 3, 4, 5], 3)
# Should return [[1, 2, 3], [4, 5]] or the iterator equivalent.
答案 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中:)