Python在包含dataclass列表的dataclass中按字段值定位更新项
高效更新StockData中PartData属性的解决方案
方案1:新增内部索引(最优,时间复杂度O(1))
通过在StockData中维护一个id到PartData实例的私有映射字典,新增部件时同步更新索引,更新时直接查索引即可,完全避免遍历。
优化后代码实现
from dataclasses import dataclass, field from typing import List, Dict @dataclass class PartData: id: int = 0 name: str = None value: int = 0 @dataclass class StockData: # 用default_factory避免可变默认值的坑 stock_1: List[PartData] = field(default_factory=list) stock_2: List[PartData] = field(default_factory=list) # 内部索引:part_id映射到对应实例,repr=False避免打印时输出索引内容 _part_index: Dict[int, PartData] = field(default_factory=dict, repr=False) def __getitem__(self, key): return super().__getattribute__(key) # 封装部件添加逻辑,自动按规则分类+更新索引 def add_part(self, part: PartData): target_stock = "stock_1" if part.id % 2 == 0 else "stock_2" self[target_stock].append(part) self._part_index[part.id] = part def update_part(self, part_id: int, value: int) -> bool: """更新对应id部件的value,更新成功返回True,未找到部件返回False""" part = self._part_index.get(part_id) if part: part.value = value return True return False
数据填充调用示例
PARTS = [{"id": 1, "name": "screw"}, {"id": 3, "name": "bolt"}, {"id": 42, "name": "glue"}, {"id": 11, "name": "nail"}, {"id": 31, "name": "hammer"}, {"id": 142, "name": "paper"}] dc_stock = StockData() for p in PARTS: dc_part = PartData(id=p["id"], name=p["name"]) dc_stock.add_part(dc_part) # 测试更新 dc_stock.update_part(1, 10) print(dc_stock)
方案2:利用现有分类规则优化(次优,时间复杂度O(k),k为单库存长度)
如果你不想修改现有数据结构和填充逻辑,可以利用你原本的分类规则(偶数id存stock_1,奇数id存stock_2)直接定位目标库存列表,避免遍历两个列表,效率比原方案提升一倍。
代码实现
@dataclass class StockData: stock_1: List[PartData] = None stock_2: List[PartData] = None def __getitem__(self, key): return super().__getattribute__(key) def update_part(self, part_id: int, value: int) -> bool: # 直接通过id判断目标库存 target_stock_name = "stock_1" if part_id % 2 == 0 else "stock_2" target_stock = getattr(self, target_stock_name, []) if not target_stock: return False for part in target_stock: if part.id == part_id: part.value = value return True return False
方案3:生成器优化写法(兼容原有逻辑,代码更简洁)
如果后续分类规则可能变动,不想依赖分类规则也不想加索引,可以用生成器表达式优化原有嵌套循环的写法,找到匹配项后立即终止遍历,代码更简洁。
代码实现
def update_part(self, part_id: int, value: int) -> bool: part = next( (p for stock in [self.stock_1, self.stock_2] if stock for p in stock if p.id == part_id), None ) if part: part.value = value return True return False
内容的提问来源于stack exchange,提问作者xtlc
相关产品推荐
相关产品推荐

