Nếu bạn không phiền khi sử dụng gói bên ngoài, bạn có thể sử dụng iteration_utilities.grouper
từ 1 . Nó hỗ trợ tất cả các lần lặp (không chỉ các chuỗi):iteration_utilties
from iteration_utilities import grouper
seq = list(range(20))
for group in grouper(seq, 4):
print(group)
bản in nào:
(0, 1, 2, 3)
(4, 5, 6, 7)
(8, 9, 10, 11)
(12, 13, 14, 15)
(16, 17, 18, 19)
Trong trường hợp độ dài không phải là bội số của nhóm, nó cũng hỗ trợ điền (nhóm cuối chưa hoàn thành) hoặc cắt bớt (loại bỏ nhóm cuối chưa hoàn thành) nhóm cuối cùng:
from iteration_utilities import grouper
seq = list(range(17))
for group in grouper(seq, 4):
print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
# (16,)
for group in grouper(seq, 4, fillvalue=None):
print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
# (16, None, None, None)
for group in grouper(seq, 4, truncate=True):
print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
Điểm chuẩn
Tôi cũng quyết định so sánh thời gian chạy của một vài phương pháp được đề cập. Đó là một biểu đồ log-log nhóm thành các nhóm yếu tố "10" dựa trên một danh sách có kích thước khác nhau. Đối với kết quả định tính: Thấp hơn có nghĩa là nhanh hơn:
Ít nhất trong tiêu chuẩn này iteration_utilities.grouper
thực hiện tốt nhất. Tiếp theo là cách tiếp cận của Craz .
Điểm chuẩn được tạo với 1 . Mã được sử dụng để chạy điểm chuẩn này là:simple_benchmark
import iteration_utilities
import itertools
from itertools import zip_longest
def consume_all(it):
return iteration_utilities.consume(it, None)
import simple_benchmark
b = simple_benchmark.BenchmarkBuilder()
@b.add_function()
def grouper(l, n):
return consume_all(iteration_utilities.grouper(l, n))
def Craz_inner(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
@b.add_function()
def Craz(iterable, n, fillvalue=None):
return consume_all(Craz_inner(iterable, n, fillvalue))
def nosklo_inner(seq, size):
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
@b.add_function()
def nosklo(seq, size):
return consume_all(nosklo_inner(seq, size))
def SLott_inner(ints, chunk_size):
for i in range(0, len(ints), chunk_size):
yield ints[i:i+chunk_size]
@b.add_function()
def SLott(ints, chunk_size):
return consume_all(SLott_inner(ints, chunk_size))
def MarkusJarderot1_inner(iterable,size):
it = iter(iterable)
chunk = tuple(itertools.islice(it,size))
while chunk:
yield chunk
chunk = tuple(itertools.islice(it,size))
@b.add_function()
def MarkusJarderot1(iterable,size):
return consume_all(MarkusJarderot1_inner(iterable,size))
def MarkusJarderot2_inner(iterable,size,filler=None):
it = itertools.chain(iterable,itertools.repeat(filler,size-1))
chunk = tuple(itertools.islice(it,size))
while len(chunk) == size:
yield chunk
chunk = tuple(itertools.islice(it,size))
@b.add_function()
def MarkusJarderot2(iterable,size):
return consume_all(MarkusJarderot2_inner(iterable,size))
@b.add_arguments()
def argument_provider():
for exp in range(2, 20):
size = 2**exp
yield size, simple_benchmark.MultiArgument([[0] * size, 10])
r = b.run()
1 Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả của các thư viện iteration_utilities
và simple_benchmark
.