将列表分割成 n 个几乎等长的分区
我正在寻找一种快速、干净、Pythonic 的方法来将列表精确地划分为 n 个几乎相等的分区。
partition([1,2,3,4,5],5)->[[1],[2],[3],[4],[5]]
partition([1,2,3,4,5],2)->[[1,2],[3,4,5]] (or [[1,2,3],[4,5]])
partition([1,2,3,4,5],3)->[[1,2],[3,4],[5]] (there are other ways to slice this one too)
这里有几个答案迭代列表切片,它们的运行非常接近我想要的,除了他们关注列表的大小,而我关心列表的数量(其中一些还用 None 填充)。显然,这些都经过了简单的转换,但我正在寻找最佳实践。
同样,人们在这里指出了很好的解决方案 如何将列表分割成大小均匀的块? 对于一个非常相似的问题,但我对分区的数量比具体大小更感兴趣,只要它在 1 之内。同样,这很简单敞篷车,但我正在寻找最佳实践。
I'm looking for a fast, clean, pythonic way to divide a list into exactly n nearly-equal partitions.
partition([1,2,3,4,5],5)->[[1],[2],[3],[4],[5]]
partition([1,2,3,4,5],2)->[[1,2],[3,4,5]] (or [[1,2,3],[4,5]])
partition([1,2,3,4,5],3)->[[1,2],[3,4],[5]] (there are other ways to slice this one too)
There are several answers in here Iteration over list slices that run very close to what I want, except they are focused on the size of the list, and I care about the number of the lists (some of them also pad with None). These are trivially converted, obviously, but I'm looking for a best practice.
Similarly, people have pointed out great solutions here How do you split a list into evenly sized chunks? for a very similar problem, but I'm more interested in the number of partitions than the specific size, as long as it's within 1. Again, this is trivially convertible, but I'm looking for a best practice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
只是不同的做法,只有在您的示例中
[[1,3,5],[2,4]]
是可接受的分区时才有效。这满足@Daniel Stutzbach 的示例中提到的示例:
Just a different take, that only works if
[[1,3,5],[2,4]]
is an acceptable partition, in your example.This satisfies the example mentioned in @Daniel Stutzbach's example:
这是一个与 Daniel 类似的版本:它尽可能均匀地划分,但将所有较大的分区放在开头:
它还避免使用浮点运算,因为这总是让我感到不舒服。 :)
编辑:一个例子,只是为了展示与 Daniel Stutzbach 的解决方案的对比
Here's a version that's similar to Daniel's: it divides as evenly as possible, but puts all the larger partitions at the start:
It also avoids the use of float arithmetic, since that always makes me uncomfortable. :)
Edit: an example, just to show the contrast with Daniel Stutzbach's solution
Python 3 版本:
Python 3 version:
下面是一种方法。
如果 len(lst) 不能被 n 整除,则此版本将以大致相等的间隔分配额外的项目。例如:
如果您不介意所有 11 都位于开头或结尾,则代码可能会更简单。
Below is one way.
If len(lst) cannot be evenly divided by n, this version will distribute the extra items at roughly equal intervals. For example:
The code could be simpler if you don't mind all of the 11s being at the beginning or the end.
这个答案为人们提供了一个函数
split(list_, n, max_ratio)
想要将列表分成
n
块,最多使用max_ratio
片长之比。它允许比
提问者的“片段长度最多有 1 个差异”。
它的工作原理是在所需比率范围内对 n 件长度进行采样
[1 , max_ratio),将它们依次放置以形成“破碎”
坚持“断点”之间的距离正确,但错误
总长度。将折断的棍子缩放到所需的长度可以得到
我们想要的断点的大致位置。获取整数
断点需要后续舍入。
不幸的是,四舍五入可能会使作品变得太短,
并让你超过max_ratio。请参阅此答案的底部
例子。
您可以像这样尝试一下:
不良结果的示例:
This answer provides a function
split(list_, n, max_ratio)
, for peoplewho want to split their list into
n
pieces with at mostmax_ratio
ratio in piece length. It allows for more variation than the
questioner's 'at most 1 difference in piece length'.
It works by sampling n piece lengths within the desired ratio range
[1 , max_ratio), placing them after each other to form a 'broken
stick' with the right distances between the 'break points' but the wrong
total length. Scaling the broken stick to the desired length gives us
the approximate positions of the break points we want. To get integer
break points requires subsequent rounding.
Unfortunately, the roundings can conspire to make pieces just too short,
and let you exceed the max_ratio. See the bottom of this answer for an
example.
You can try it out like so:
Example of a bad result: