如何创建长度几乎相等的列表的分块列表?

How to create a chunked list of lists with almost-equal lengths?

提问人:enzo 提问时间:11/15/2023 最后编辑:quamranaenzo 更新时间:11/15/2023 访问量:52

问:

我需要将一个数字分成 3 个部分。以下函数()可以正确地执行此操作:

def parts(num: int, div: int) -> list[int]:
    """Split a number into equal parts."""
    return [num // div + (1 if x < num % div else 0) for x in range(div)]

所以

assert parts(8, 3) == [3, 3, 2]
assert parts(9, 3) == [3, 3, 3]
assert parts(10, 3) == [4, 3, 3]

从该列表中,我需要一个包含从 0 到 的列表列表,以便每个子列表num + 3

  • 在偶数索引处,长度为 1
  • 在奇数索引处,其长度为 ,其中从nnparts
assert expected(8, 3) == [[0], [1, 2, 3], [4], [5, 6, 7], [8], [9, 10]]
assert expected(9, 3) == [[0], [1, 2, 3], [4], [5, 6, 7], [8], [9, 10, 11]]
assert expected(10, 3) == [[0], [1, 2, 3, 4], [5], [6, 7, 8], [9], [10, 11, 12]]

这是我尝试过的:

def actual(num: int, div: int) -> list[list[int]]:
    matrix: list[list[int]] = []
    for i, length in enumerate(parts(num, div)):
        base = i * (length + 1)
        matrix.append([base])
        matrix.append([base + j + 1 for j in range(length)])

    return matrix

但是,它仅在可被 整除时才有效。我该如何解决?numdiv

这些是我的函数的输出:

assert actual(8, 3) == [[0], [1, 2, 3], [4], [5, 6, 7], [6], [7, 8]]
assert actual(9, 3) == [[0], [1, 2, 3], [4], [5, 6, 7], [8], [9, 10, 11]]
assert actual(10, 3) == [[0], [1, 2, 3, 4], [4], [5, 6, 7], [8], [9, 10, 11]]
函数 python-3.8

评论

0赞 Kelly Bundy 11/16/2023
为什么参数始终为 3 时存在?div
0赞 enzo 11/16/2023
@KellyBundy 因为如果将来此需求发生变化,则更容易调整代码。

答:

1赞 Frank Yellin 11/15/2023 #1

而不是使用 ,从(在循环之前)开始,然后按您在该迭代中添加的元素数量递增。base = i * (length + 1)base = 0base

def actual(num: int, div: int) -> list[list[int]]:
    base = 0
    matrix: list[list[int]] = []
    for i, length in enumerate(parts(num, div)):
        matrix.append([base])
        matrix.append([base + j + 1 for j in range(length)])
        base += 1+ length
    return matrix

评论

0赞 enzo 11/15/2023
你的回答对我来说效果很好,非常感谢!我忘了在每次迭代之间跟踪。但是,我真的很喜欢另一个答案的功能方法。base
0赞 Frank Yellin 11/15/2023
我故意试图向你展示代码中的错误,而不是从头开始重写算法。我也喜欢其他解决方案。
1赞 quamrana 11/15/2023 #2

看起来每个子列表都包含递增的数字。这是可以给你的。itertools.count

我已经调整了您的功能以如下方式使用它:

from itertools import count

def actual(num: int, div: int) -> list[list[int]]:
    matrix: list[list[int]] = []
    base = count(0)
    for length in parts(num, div):
        matrix.append([next(base)])
        matrix.append([next(base) for _ in range(length)])

    return matrix

评论

0赞 enzo 11/15/2023
你的回答不涉及算术,也删除了 和 .我一直在寻找这样的东西!ij