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

如何从CSV文件生成按Rack分组的字典列表?

问题描述

现有如下结构的CSV文件,包含Rack、Tube、Well、sample_vol、solvent_vol列:

RackTubeWellsample_volsolvent_vol
10A1230400
11B120020
22G1530
31A19040
320A110090

需求是:为每个不同的Rack值创建一个字典,字典以Tube为键、sample_vol为值,最终将这些字典整合到一个列表中,期望输出如下:

print(rack_list)
[{'0':230,'1':200},{'2':5},{'1':90,'20':100}]

注:原示例输出中第三个字典的20对应值应为100,此处修正了笔误

目前编写的Python代码卡在按Rack分组生成字典列表的步骤:

csv_reader = csv.DictReader(csvfile)
header = csv_reader.fieldnames
solvent_volume_map = {}
sample_volume_map = {}
max_rack = None
rack = None
rack_list = []
for csv_row in csv_reader:
    rack = int(csv_row["Rack"])
    if max_rack == None or max_rack < rack:
      max_rack = rack
    destination_well = csv_row['Well']
    source_tube = csv_row['Tube']
    source_rack = csv_row['Rack']
    print(source_rack)
    try:
        solvent_volume = float(csv_row['solvent_vol'])
        sample_volume = float(csv_row['sample_vol'])
    except ValueError as e:
        # blank csv entry
        solvent_volume = "skip"
        sample_volume = "skip"
    solvent_volume_map[destination_well] = solvent_volume
    for i in range(max_rack):
      sample_volume_map[source_tube] = sample_volume
      rack_list.append(sample_volume_map)
解决方案

原代码的问题在于未正确按Rack分组,且循环中重复添加同一个字典对象,导致结果不符合预期。以下是两种可行的实现方式:

方法一:普通字典分组

先按Rack编号分组存储每个Tube对应的sample_vol,最后按Rack顺序整理成列表:

import csv

rack_dict = {}  # 键为Rack编号,值为对应Tube-sample_vol的字典

with open('your_file.csv', 'r') as csvfile:
    csv_reader = csv.DictReader(csvfile)
    for row in csv_reader:
        rack_num = int(row["Rack"])
        tube = row["Tube"]
        try:
            sample_vol = float(row["sample_vol"])
        except ValueError:
            sample_vol = "skip"
        
        # 若当前Rack未在分组字典中,先创建空字典
        if rack_num not in rack_dict:
            rack_dict[rack_num] = {}
        rack_dict[rack_num][tube] = sample_vol

# 按Rack编号从小到大排序,提取对应字典组成目标列表
rack_list = [rack_dict[num] for num in sorted(rack_dict.keys())]
print(rack_list)

方法二:使用itertools.groupby(需先按Rack排序)

groupby要求数据先按分组键排序,因此需先对CSV行按Rack字段排序:

import csv
from itertools import groupby

with open('your_file.csv', 'r') as csvfile:
    csv_reader = csv.DictReader(csvfile)
    # 按Rack字段排序,转换为整数确保排序逻辑正确
    sorted_rows = sorted(csv_reader, key=lambda x: int(x["Rack"]))
    
    rack_list = []
    # 按Rack分组处理
    for rack_key, group in groupby(sorted_rows, key=lambda x: int(x["Rack"])):
        tube_map = {}
        for row in group:
            tube = row["Tube"]
            try:
                sample_vol = float(row["sample_vol"])
            except ValueError:
                sample_vol = "skip"
            tube_map[tube] = sample_vol
        rack_list.append(tube_map)

print(rack_list)

两种方法运行后都会输出符合预期的结果:

[{'0': 230.0, '1': 200.0}, {'2': 5.0}, {'1': 90.0, '20': 100.0}]

若需要整数类型的sample_vol,可将代码中的float替换为int,根据实际数据情况调整即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 03:01:20