如何访问存储NamedTuple的多维列表的全量指定属性值?
问题原因
你当前使用的是Python原生二维列表,列表作为通用容器不会自动聚合内部存储的Halo实例属性,ID是Halo类的属性而非列表类的属性,因此直接调用halo_arr.ID必然抛出AttributeError。
另外你提供的单元素访问示例有语法错误,正确写法应为print(halo_arr[0][5].ID),圆括号会被识别为函数调用触发报错。
解决方案
下面提供三种不同复杂度的适配方案,可根据你的使用场景选择:
方案1:无侵入式快速实现(无需修改现有数据结构)
直接通过嵌套列表推导式生成对应属性的二维数组,可直接传入HDF5写入接口,代码量最少:
# 生成ID二维数组 id_arr = [[item.ID for item in row] for row in halo_arr] # 直接写入hdf5 fh5.create_dataset("/Halos/IDs", data=id_arr)
方案2:自定义容器类(完全匹配你期望的.属性调用方式)
封装原生列表,通过@property装饰器实现属性的自动聚合,原有填充、索引访问逻辑完全不需要修改:
from typing import NamedTuple, List class Halo(NamedTuple): ID: int axis: str event_file: str class HaloList: def __init__(self, nperbin: int, nhalo_bins: int): # 初始化底层二维存储 self._data: List[List[Halo]] = [[None for _ in range(nhalo_bins)] for _ in range(nperbin)] # 支持原有索引访问逻辑:halo_arr[i][j] def __getitem__(self, index: int): return self._data[index] # 支持原有赋值逻辑:halo_arr[i][j] = Halo(...) def __setitem__(self, index: int, value: List[Halo]): self._data[index] = value @property def ID(self) -> List[List[int]]: return [[item.ID for item in row] for row in self._data] @property def axis(self) -> List[List[str]]: return [[item.axis for item in row] for row in self._data] @property def event_file(self) -> List[List[str]]: return [[item.event_file for item in row] for row in self._data]
使用时只需要修改初始化代码即可:
# 原来的初始化替换为 halo_arr = HaloList(nperbin, nhalo_bins)
后续即可直接使用halo_arr.ID、halo_arr.axis等调用方式,完全符合你的使用习惯。
方案3:结构化数组(适合大规模数据、高性能场景)
如果你的数据量较大,推荐使用NumPy结构化数组,读写效率远高于列表,且原生支持按属性名访问整列数据:
import numpy as np # 定义结构化数组类型,对应Halo的三个属性 halo_dtype = [ ("ID", "i4"), # 4字节整型,可根据ID范围调整为i8 ("axis", "U10"), # 最长10位字符串,可按需调整长度 ("event_file", "U256") # 最长256位文件路径 ] # 初始化二维结构化数组 halo_arr = np.zeros((nperbin, nhalo_bins), dtype=halo_dtype)
赋值逻辑和原来基本一致:
halo_arr[nhalos[hbin]][hbin] = (int(IDarr_shuf[j][i]), axis_arr[j], evt_file)
直接按属性名访问对应二维数组:
print(halo_arr["ID"]) fh5.create_dataset("/Halos/IDs", data=halo_arr["ID"])
内容的提问来源于stack exchange,提问作者Ben O.
相关产品推荐
相关产品推荐

