python - 将列表拆分成块,块之间有重复

我有一个元素数组,例如 r = np.arange(15)。我正在尝试将此数组拆分为连续元素的块,其中每个块(可能是最后一个块除外)的大小为 M 并且每对块之间有 m 重复元素。

例如:split_to_chunks(np.arange(15), M=5, m=1) 应该产生四个列表:[0, 1, 2, 3, 4][4, 5, 6, 7, 8][8, 9, 10, 11, 12][12, 13, 14]

显然这可以迭代地完成,但我正在寻找一种更“pythonic”(和更快)的方式来做到这一点。

回答1

像这样的列表理解:

[l[i*(M-m):i*(M-m)+M] for i in range(math.ceil((len(l)-m)/(M-m)))]

例子:

import math
l = list(range(15))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
m, M = 2, 5
[l[i*(M-m):i*(M-m)+M] for i in range(math.ceil((len(l)-m)/(M-m)))]
# [[0, 1, 2, 3, 4],
# [3, 4, 5, 6, 7],
# [6, 7, 8, 9, 10],
# [9, 10, 11, 12, 13],
# [12, 13, 14]]

m, M = 3, 5
[l[i*(M-m):i*(M-m)+M] for i in range(math.ceil((len(l)-m)/(M-m)))]
# [[0, 1, 2, 3, 4],
#  [2, 3, 4, 5, 6],
#  [4, 5, 6, 7, 8],
#  [6, 7, 8, 9, 10],
#  [8, 9, 10, 11, 12],
#  [10, 11, 12, 13, 14]]

l = range(5)
m, M = 2, 3
[l[i*(M-m):i*(M-m)+M] for i in range(math.ceil((len(l)-m)/(M-m)))]
# [range(0, 3), range(1, 4), range(2, 5)]

解释:

i 从索引 i*(M-m) 开始,并在后面的 M 个位置结束索引 i*(M-m) + M

chunk index    starts           ends
-------------------------------------------------
0              0                M
1              M-m              M-m+M = 2*M-m
2              2*M-m-m=2(M-m)   2*(M-m)+M = 3M-2m
...

现在的问题是确定有多少块。

在每一步中,我们将初始索引增加 M-m,因此要计算总步数,我们需要将列表的长度除以 M-m(但在减去 m 之后,因为在第一个块中我们不是跳过任何东西)。

最后,使用上限函数添加最后一个不完整的块,以防划分不准确。

回答2

这应该做的工作:

def split_to_chunks(r, M=5, m=1):
    return [r[i*(M-m): (i+1)*M-i*m] for i in range(len(r)//(M-m)+1) if i*(M-m) < len(r)]

说明:在列表理解循环中以问题中解释的方式遍历索引。块的每个开始都将从 i*(M-m) 开始并在 (i+1)*M-i*m 结束。最后,如果块的开始在数组长度之后,它将跳过它。

相似文章

scala - 多个列表的组合 (Scala)

我正在尝试编写一个函数,该函数将多个列表作为输入并返回这些列表之间每个组合的字符串表示形式。样本输入:valintegers=List(1,2,3,4)valcharacters=List('a','...

c++ - 为 n-queen 问题创建回溯 Algorithm

我试图通过回溯找到解决n-queen问题的方法。我已经创建了一个板,并且我想我已经创建了检查一块是否可以放置在位置column2的函数,与位置column1的一块相比。而且我想我想以某种方式遍历列,以...