从环绕的列表中读取批

2024-03-29 11:57:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下情况。假设我有一个变量batch_size和一个名为data的列表。我想把batch_size元素从data中拉出,这样当我到达终点时,我就绕过去了。换句话说:

data =[1,2,3,4,5]
batch_size = 4
-> [1,2,3,4], [5,1,2,3], [4,5,1,2], ...

有没有一些很好的惯用方法来返回这样的切片?开始索引总是batch_size * batch模化data的长度,但是如果batch_size * (batch+1)超出了列表的长度,是否有一种简单的方法从开始就“环绕”?在这种情况下,我当然可以把两片拼接起来,但我希望有一种真正干净的方法。你知道吗

我唯一的假设是batch_size < len(data)。你知道吗


Tags: 方法元素列表datasizelenbatch情况
2条回答

您还可以使用来自collections模块的deque,并在deques上进行一次旋转,如以下示例所示:

from collections import deque

def grouper(iterable, elements, rotations):
    if elements > len(iterable):
        return []

    b = deque(iterable)
    for _ in range(rotations):
        yield list(b)[:elements]
        b.rotate(1)


data = [1,2,3,4,5]
elements = 4
rotations = 5
final = list(grouper(data, elements, rotations))
print(final)

输出:

[[1, 2, 3, 4], [5, 1, 2, 3], [4, 5, 1, 2], [3, 4, 5, 1], [2, 3, 4, 5]]

您可以使用itertools的itertools.cyclegrouper配方

import itertools

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x')  > ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)

data = [1,2,3,4,5]
batch_size = 4
how_many_groups = 5

groups = grouper(itertools.cycle(data), batch_size)
chunks = [next(groups) for _ in range(how_many_groups)]

块的结果是:

[(1, 2, 3, 4),
 (5, 1, 2, 3),
 (4, 5, 1, 2),
 (3, 4, 5, 1),
 (2, 3, 4, 5)]

因此,如果您真的需要这些列表,那么您必须将其转换为列表([list(next(groups)) for ...]

相关问题 更多 >