Python如何比较两个类对象列表区分相同与差异实现课程数据同步
解决方案
1. 优化Courses类定义
你原来的__eq__实现不符合需求:你只需要通过referenceId判断是否为同一课程,其他字段差异属于版本更新范畴,不需要放在相等判断里。同时补充__hash__方法方便后续做集合/字典索引:
from dataclasses import dataclass from datetime import datetime @dataclass class Courses: id: str title: str description: str courseUrl: str referenceId: str providerId: int publishingState: str createdAt: str updatedAt: str def __eq__(self, other): if isinstance(other, Courses): # 仅用referenceId判断是否为同一课程 return self.referenceId == other.referenceId return False def __hash__(self): # 哈希值也基于referenceId生成,和__eq__逻辑对齐 return hash(self.referenceId) def is_newer_than(self, other: "Courses") -> bool: # 封装版本判断逻辑,避免字符串比较风险,统一转datetime self_created = datetime.fromisoformat(self.createdAt.rstrip("Z")) other_created = datetime.fromisoformat(other.createdAt.rstrip("Z")) return self_created > other_created
2. 核心业务逻辑实现
用字典做O(1)复杂度的索引,全程没有多层循环,代码简洁易懂,还能避免你原实现中「遍历列表时删除元素导致索引错乱漏项」的问题:
internal_courses = get_courses(request) # 一行代码生成内部课程的referenceId索引字典,复杂度O(n) internal_course_map = {c.referenceId: c for c in internal_courses} # 筛选待插入/更新的课程:要么是新增的(referenceId不在内部库),要么是版本更新的 to_upsert = [] ext_reference_ids = set() for ext_course in external_courses: ext_reference_ids.add(ext_course.referenceId) # 不在内部库,直接加入待插入列表 if ext_course.referenceId not in internal_course_map: to_upsert.append(ext_course) # 在内部库,判断版本是否更新,更新就加入待更新列表 elif ext_course.is_newer_than(internal_course_map[ext_course.referenceId]): to_upsert.append(ext_course) # 一行代码拿到需要删除的课程:内部库有但外部返回中不存在的 to_delete = [c for c in internal_courses if c.referenceId not in ext_reference_ids]
简化方案(无需处理版本更新时可用)
如果不需要判断版本新旧,仅需要新增、删除差异项,直接用集合运算即可:
# 新增课程:外部有内部没有的 to_insert = list(set(external_courses) - set(internal_courses)) # 待删除课程:内部有外部没有的 to_delete = list(set(internal_courses) - set(external_courses))
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

