如何在 python 中获取列表的第 n 个项目块?
how to get nth chunks of items of a list in python?
我想获取项目列表的每 4 个块,其中第一个项目的索引对应于 4-1,所以是上一步。我只能得到每 4 个块,但我坚持让列表中的每一项都从“上一步”或 4-1 开始。
我应该以不同的方式循环吗?
当前代码:
l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
four_chunks = [l[x:x+4] for x in range(0, len(l), 4)]
##output of four_chunks:
[['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]
期望输出:
[['a', 'b', 'c', 'd'], ['d', 'e', 'f', 'g'], ['g', 'h', 'i', 'j']]
正如您在所需输出中看到的那样,每个块都以一个结束前一个块的项目开头。例如。项目 [1] 以 'd' 开头,而不是 'e'.
正如Veedrac和guorui所说,你需要选择3作为range
的step
参数。
four_chunks = [l[x:x+4] for x in range(0, len(l), 3)]
# or
four_chunks = [l[x:x+4] for x in range(0, len(l) - 3, 3)]
有什么区别?如果你的列表不能分成相等的块(所以 len(l) % 3 != 1
)后者将切割最后一个块,前者的最后一个块大小 < 4
我对这个问题感兴趣并提出了一个 iterator-based 解决方案。我从 pairwise
和其他人那里借了很多东西。
这是我想出的:
from itertools import tee, islice
def overlapping_chunks(iterable, n):
iters = tuple(it for _, it in (tee(iterable) for _ in range(n)))
# advance iters by i
for i, it in enumerate(iters):
next(islice(it, i, i), None)
# make all iters step by n-1
return zip(*(islice(it, None, None, n - 1) for it in iters))
已应用于您的列表:
l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
print(list(overlapping_chunks(iterable=l, n=4)))
# -> [('a', 'b', 'c', 'd'), ('d', 'e', 'f', 'g'), ('g', 'h', 'i', 'j')]
这有一个(小)优势,即如果您遍历各个部分,则不必创建整个列表:
for part in overlapping_chunks(iterable=l, n=4):
print(part)
我想获取项目列表的每 4 个块,其中第一个项目的索引对应于 4-1,所以是上一步。我只能得到每 4 个块,但我坚持让列表中的每一项都从“上一步”或 4-1 开始。
我应该以不同的方式循环吗?
当前代码:
l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
four_chunks = [l[x:x+4] for x in range(0, len(l), 4)]
##output of four_chunks:
[['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]
期望输出:
[['a', 'b', 'c', 'd'], ['d', 'e', 'f', 'g'], ['g', 'h', 'i', 'j']]
正如您在所需输出中看到的那样,每个块都以一个结束前一个块的项目开头。例如。项目 [1] 以 'd' 开头,而不是 'e'.
正如Veedrac和guorui所说,你需要选择3作为range
的step
参数。
four_chunks = [l[x:x+4] for x in range(0, len(l), 3)]
# or
four_chunks = [l[x:x+4] for x in range(0, len(l) - 3, 3)]
有什么区别?如果你的列表不能分成相等的块(所以 len(l) % 3 != 1
)后者将切割最后一个块,前者的最后一个块大小 < 4
我对这个问题感兴趣并提出了一个 iterator-based 解决方案。我从 pairwise
和其他人那里借了很多东西。
这是我想出的:
from itertools import tee, islice
def overlapping_chunks(iterable, n):
iters = tuple(it for _, it in (tee(iterable) for _ in range(n)))
# advance iters by i
for i, it in enumerate(iters):
next(islice(it, i, i), None)
# make all iters step by n-1
return zip(*(islice(it, None, None, n - 1) for it in iters))
已应用于您的列表:
l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
print(list(overlapping_chunks(iterable=l, n=4)))
# -> [('a', 'b', 'c', 'd'), ('d', 'e', 'f', 'g'), ('g', 'h', 'i', 'j')]
这有一个(小)优势,即如果您遍历各个部分,则不必创建整个列表:
for part in overlapping_chunks(iterable=l, n=4):
print(part)