通过指定组 ID 将列表分成组

Partition a list into groups by specifying group ID

我有一个列表,说:

my_list = [1,2,3,4,5,6,7]

我想创建另一个包含组 ID 的列表,例如,如果我将 my_list 分成 2 个组,组 ID 列表将是:

group_id = [1,1,1,2,2,2,2]

由于 my_list 包含素数元素,因此最后一组包含 1 个元素。

这里是所有可能的拆分,从 7 组到 1 组:

group_id = [1,2,3,4,5,6,7]  # 7 groups, 7 elements
group_id = [1,1,2,3,4,5,6]  # 6 groups, 7 elements
group_id = [1,1,2,2,3,4,5]  # 5 groups, 7 elements
group_id = [1,1,2,2,3,3,4]  # 4 groups, 7 elements
group_id = [1,1,1,2,2,2,3]  # 3 groups, 7 elements
group_id = [1,1,1,2,2,2,2]  # 2 groups, 7 elements
group_id = [1,1,1,1,1,1,1]  # 1 group, 7 elements.

问题是我不知道如何强制执行组的大小需要大致相等的条件。这必须适用于任何列表长度(不仅是 7),并为我提供给定数量的组(从 1 到 len(my_list))的 group_id 列表。

编辑:

这似乎 "somewhat" 有效,但不完全:

import math

my_list = [1,2,3,4,5,6,7]
n_groups = 3


k = math.ceil(len(my_list)/n_groups)
chunks = [my_list[x:x+k] for x in range(0, len(my_list), k)]
group_id_nested = [[chunks.index(i)+1]*len(i) for i in chunks]
group_id = [item for sublist in group_id_nested for item in sublist]

如果您被允许使用 numpy,您可以通过以下方式利用 numpy.linspace 完成该任务:

import numpy as np
list_size = 7
for n in range(1,list_size+1):
    group_ids = list(map(int,map(round,np.linspace(1,n,num=list_size))))
    print(group_ids)

输出:

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

想法很简单:我得到从1(含)到n(含)的均匀间隔(浮动)数字(其中list_size)然后得到最近的整数(注意round的用法)。正如您在每行输出中看到的那样,任意两个组大小(给定数字的出现次数)之间的差异始终等于或小于 2。

没有 numpy:

import math
listy = [1,2,3,4,5,6,7]
groupnum = 6

smallnum = math.floor(len(listy)/groupnum)
bignum = math.ceil(len(listy)/groupnum)

grouped = []
for c,e in enumerate(range(1,groupnum+1)):
    if c<(len(listy)/groupnum - smallnum)*groupnum:
        grouped+=[e]*bignum
    else:
        grouped+=[e]*smallnum
grouped=grouped[0:len(listy)]
print(grouped)

此外,它均匀分布它们。例如,它将 [1, 1, 2, 2, 3, 3, 4] 而不是 [1, 2, 2, 2, 3, 4, 4] 分成 4 组。