如何高效合并两个不同结构的Python对象列表(按属性匹配)
高效合并不同结构的Python对象列表
需求:合并两个结构不同的Python类对象列表,将StructureTwo中的value匹配到StructureOne对应的date_time条目上,最终得到填充好value的StructureOne列表,要求不使用外部库。
原始实现代码
from datetime import datetime class StructureOne(object): def __init__(self, date_time: datetime, name: str): self.date_time: datetime = date_time self.name: str = name self.value = None def set_value(self,value:float): self.value = value class StructureTwo(object): def __init__(self, date_time: datetime, value: float): self.date_time = date_time self.value: float = value def merge_lists(list_one: list[StructureOne], list_two: list[StructureTwo]) -> list[StructureOne]: for element_one in list_one: i = 0 while i < len(list_two) and element_one.value is None: if element_one.date_time == list_two[i].date_time: element_one.set_value(value=list_two[i].value) i += 1 return list_one list_one: list[StructureOne] = [ StructureOne(date_time=datetime(2022, 1, 1, 0), name='zero'), StructureOne(date_time=datetime(2022, 1, 1, 1), name='one'), StructureOne(date_time=datetime(2022, 1, 1, 2), name='two'), StructureOne(date_time=datetime(2022, 1, 1, 3), name='three'), ] list_two: list[StructureTwo] = [ StructureTwo(date_time=datetime(2022, 1, 1, 0), value=0), StructureTwo(date_time=datetime(2022, 1, 1, 1), value=1), StructureTwo(date_time=datetime(2022, 1, 1, 2), value=2), StructureTwo(date_time=datetime(2022, 1, 1, 3), value=3), ] merged_list: list[StructureOne] = merge_lists(list_one=list_one, list_two=list_two)
原始实现的问题
原始方法采用嵌套循环,时间复杂度为O(n*m)(n是list_one长度,m是list_two长度),当列表规模较大时,效率会显著下降。
优化后的实现
核心思路是先将list_two转换为以date_time为键、value为值的字典,这样查找匹配项的时间复杂度降为O(1),整体时间复杂度优化为O(n+m),大幅提升效率:
from datetime import datetime class StructureOne(object): def __init__(self, date_time: datetime, name: str): self.date_time: datetime = date_time self.name: str = name self.value = None def set_value(self, value: float): self.value = value # 可选:添加__repr__方法方便查看结果 def __repr__(self): return f"StructureOne(date_time={self.date_time}, name='{self.name}', value={self.value})" class StructureTwo(object): def __init__(self, date_time: datetime, value: float): self.date_time = date_time self.value: float = value def merge_lists(list_one: list[StructureOne], list_two: list[StructureTwo]) -> list[StructureOne]: # 将list_two转换为date_time到value的映射字典 value_map = {item.date_time: item.value for item in list_two} # 遍历list_one,直接通过字典匹配赋值 for element in list_one: if element.date_time in value_map: element.set_value(value_map[element.date_time]) return list_one list_one: list[StructureOne] = [ StructureOne(date_time=datetime(2022, 1, 1, 0), name='zero'), StructureOne(date_time=datetime(2022, 1, 1, 1), name='one'), StructureOne(date_time=datetime(2022, 1, 1, 2), name='two'), StructureOne(date_time=datetime(2022, 1, 1, 3), name='three'), ] list_two: list[StructureTwo] = [ StructureTwo(date_time=datetime(2022, 1, 1, 0), value=0), StructureTwo(date_time=datetime(2022, 1, 1, 1), value=1), StructureTwo(date_time=datetime(2022, 1, 1, 2), value=2), StructureTwo(date_time=datetime(2022, 1, 1, 3), value=3), ] merged_list: list[StructureOne] = merge_lists(list_one=list_one, list_two=list_two) print(merged_list)
验证结果
运行优化后的代码,输出结果与预期一致:
[ StructureOne(date_time=2022-01-01 00:00:00, name='zero', value=0), StructureOne(date_time=2022-01-01 01:00:00, name='one', value=1), StructureOne(date_time=2022-01-01 02:00:00, name='two', value=2), StructureOne(date_time=2022-01-01 03:00:00, name='three', value=3) ]
内容的提问来源于stack exchange,提问作者Anabel
相关产品推荐
相关产品推荐

