You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将列表按正态分布划分为12个无重复耗尽式分块?

问题描述
  • 将包含数千条元素的列表划分为12个分块
  • 分块元素数量遵循对称正态分布:中间分块(约4-8号)元素最多,向两端(0-3号、9-11号)逐步减少
  • 分块间无重复元素,原列表所有元素必须被完全分配
  • 输入数据示例:
['6355ab76f70c5c59749f2018',
 '6355c797f70c5c5974a1cb15',
 '6355d256f70c5c5974a36a6c',
 ...
 '6355edb3f70c5c5974ab790b']
  • 期望输出格式:
[
    { 0: ['6355ab76f70c5c59749f2018', '6355c797f70c5c5974a1cb15', ...] },
    { 1: ['6355d270f70c5c5974a37356', ...] },
    ...
]

现有尝试的代码

已尝试用numpy编写两个函数,但输出不符合预期:

import numpy as np

def divide_list_normal(lst):
    normal_dist = np.random.normal(size=len(lst)) # Generate a normal distribution of numbers
    sorted_list = [x for _,x in sorted(zip(normal_dist,lst))] # Sort the list according to the normal distribution
    chunk_size = int(len(lst)/len(normal_dist)) # Divide the list into chunks
    chunks = [sorted_list[i:i+chunk_size] for i in range(0, len(sorted_list), chunk_size)]
    return chunks 

def divide_list_normal_define_chunk_size(lst, n):
    normal_dist = np.random.normal(size=len(lst)) # Generate a normal distribution of numbers
    sorted_list = [x for _,x in sorted(zip(normal_dist,lst))] # Sort the list according to the normal distribution
    chunk_size = int(len(lst)/len(normal_dist)) # Divide the list into chunks
    chunks = [sorted_list[i:i+chunk_size] for i in range(0, n, chunk_size)]
    return chunks

可行实现方案

核心思路:先生成符合对称正态分布的12个分块大小(总和等于原列表长度),再按此大小切割列表。

实现步骤

  1. 生成12个对称的正态分布数值,作为分块大小的基础
  2. 将数值归一化后乘以原列表总长度,得到初始分块大小
  3. 调整分块大小,确保总和严格等于原列表长度(避免浮点误差)
  4. 打乱原列表(可选,保证元素分配的随机性)
  5. 按调整后的分块大小依次切割列表,包装为期望的字典格式

完整代码

import numpy as np

def split_list_into_normal_chunks(lst, num_chunks=12):
    # 生成对称的正态分布分块权重(中心在中间位置)
    x = np.linspace(-3, 3, num_chunks)
    weights = np.exp(-x**2 / 2) / np.sqrt(2 * np.pi)
    
    # 归一化权重,计算初始分块大小
    total_elements = len(lst)
    chunk_sizes = np.round(weights / weights.sum() * total_elements).astype(int)
    
    # 调整分块大小,确保总和等于总元素数
    diff = total_elements - chunk_sizes.sum()
    if diff != 0:
        sorted_indices = np.argsort(weights)[::-1]
        for i in range(abs(diff)):
            chunk_sizes[sorted_indices[i]] += 1 if diff > 0 else -1
    
    # 打乱原列表(不需要随机分配可注释此行)
    shuffled_lst = lst.copy()
    np.random.shuffle(shuffled_lst)
    
    # 切割列表并包装为目标格式
    result = []
    start_idx = 0
    for idx, size in enumerate(chunk_sizes):
        end_idx = start_idx + size
        chunk = shuffled_lst[start_idx:end_idx]
        result.append({idx: chunk})
        start_idx = end_idx
    
    return result

代码说明

  • 用np.linspace(-3,3,12)生成对称的12个横轴点,确保分块大小的对称分布
  • 通过正态分布概率密度计算权重,保证中间分块权重最高,两端逐步递减
  • 分块大小调整步骤解决了浮点运算导致的总和偏差,确保所有元素都被分配
  • 可选的打乱操作保证元素分配的随机性,若需保留原列表顺序可移除该步骤

内容的提问来源于stack exchange,提问作者rom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 04:01:19