【问题标题】:Compare two lists of class objects and keep the difference and the equals in Python比较两个类对象列表并在 Python 中保持差异和相等
【发布时间】:2021-09-10 17:21:38
【问题描述】:

我目前陷入困境,我希望这里有人可以帮助我。我想要实现的目标如下:我有两个 API,它们分别为我提供了一个以 python 类实例表示的学习课程列表。一方面是 MS Learn API,工作流程是我获取它们、映射数据并将它们插入我的数据库中。但在我这样做之前,我想检查 1.) 重复的课程和 2.) 如果有重复 - 它可能比我在数据库中保存的课程更新吗? 3.) 我的数据库中是否有 MS Learn 课程列表中不存在的课程?

我需要检查的属性是外部欺骗/非现有课程的“referenceID”和“created_at”(如果有新/旧的东西)。而不是疯狂循环和保存不同列表中的值,我想使用更干净和pythonic的东西,比如自定义 eq 函数,然后比较整个两个类对象列表并保留 1. 所有新课程,从列表中删除受骗者和 2. 外部课程列表中不存在的差异,因此我可以删除它们

对不起,这里有一些代码:

@dataclass
class Courses:
    id: str
    title: str
    description: str
    courseUrl: str
    referenceId: str
    providerId: int
    publishingState: str
    createdAt: str
    updatedAt: str

第一次尝试自定义 eq 函数 - 如果可行,则在 idk 之前从未使用过:

def __eq__(self, other):
    if isinstance(other, Courses):
        return self.title == other.title \
               and self.description == other.description \
               and self.courseUrl == other.courseUrl \
               and self.referenceId == other.referenceId \
               and self.providerId == other.providerId \
               and self.publishingState == other.publishingState \
               and self.createdAt == other.createdAt \
               and self.updatedAt == other.updatedAt

    return False

我的循环混乱的第一次开始:

    internal_courses = get_courses(request)
    internal_reference_ids = []
    duplicated_courses = []

    for int_course in internal_courses:
        internal_reference_ids.append(int_course.referenceId)

    for ext_course in external_courses:
        if ext_course.referenceId in internal_reference_ids:
            duplicated_courses.append(ext_course)
            external_courses.remove(ext_course)

非常感谢你,我很高兴学习新东西:)

【问题讨论】:

    标签: python class list-comprehension


    【解决方案1】:

    您定义的__eq__ 方法使您能够像这样比较类实例:

    if course_a == course_b:
        # Do something
    

    比较两个列表时,您调用list.__eq__ 方法。如果此列表包含您的 Courses 对象(顺便说一句,您应该使用单数形式,因为它是单个 Course),它们将使用您定义的 __eq__ 方法进行比较。 这意味着,您只需比较 [course_a, course_b] == [course_a, course_c],它就会按您的意图工作。

    class Example:
        def __init__(self, arg1, arg2):
            self.arg1 = arg1
            self.arg2 = arg2
          
        def __eq__(self, other):
            return self.arg1 == other.arg1 and self.arg2 == other.arg2
          
    # Initialize two instances with identical arguments.
    one = Example('x', 'y')
    two = Example('x', 'y')
    
    print(one == two)   # True
    
    a = [one]
    b = [two]
    
    print(a == b)   # Also True
    

    附: 查看@dataclass(eq=True),因为它的功能几乎相同

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-26
      • 2021-02-04
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多