在這裏發佈這樣的問題不是像這樣的問題添加到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
因爲它的簡單和明顯不夠使用列表理解在一行來實現? – wim 2013-05-01 05:28:59
@wim這聽起來像是我的另一個原因:) – razpeitia 2013-05-01 05:42:54
滑動窗口迭代器將是我將添加到標準庫的另一個。 – 2013-05-01 06:10:41