このような質問をここに投稿することは、このようなものを 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