首页 > 解决方案 > 在自定义日期对象列表中查找最早日期

问题描述

给定日期对象列表,我需要找到文件中最早出现的日期

我编写了以下代码来执行此操作:

return min(dates, key=lambda x: x.year)

每个对象都有一个年、月和日属性。 我必须使用我创建的自定义类(在帖子底部)

此代码一直有效,直到有两个日期为同一年份。如果两个日期的年份相同,它会返回列表中的第一个日期,这不是预期的。

例如,这两个日期:

1988 10 10
1988 09 03

该函数应返回 1988 09 03 ,但它首先返回 1988 10 10 。

如何在python中比较一个对象的多个值?

我也试过这个

return min(min(min(dates, key=lambda x: x.year), key=lambda x: x.month), key=lambda x: x.day)

但它似乎不起作用

我也试过

return min(dates)

但这只是返回列表中的最后一个日期

日期文件样本:

1954 10 04
1987 12 20
1993 3 10
1996 7 29
1994 5 30
1993 6 9
1989 12 21
2001 6 30
1995 6 14
2002 2 28
1988 6 21
class Date(object):
    def __init__(self, year, month=1, day=1):
        self.year = year
        self.month = month
        self.day = day

    def __str__(self):
        return '{}/{}/{}'.format(self.year, self.month, self.day)

    def __lt__(self, other):
        return (self.year, self.month, self.day) < (other.year, other.month, other.day)

    def __gt__(self, other):
        return (self.year, self.month, self.day) > (other.year, other.month, other.day)

    def __eq__(self, other):
        return (self.year, self.month, self.day) == (other.year, other.month, other.day)

    def __le__(self, other):
        return (self.year, self.month. self.day) <= (other.year, other.month, other.day)

    def __ge__(self, other):
        return (self.year, self.month, self.day) >= (other.year, other.month, other.day)

    def __ne__(self, other):
        return (self.year, self.month, self.day) != (other.year, other.month, other.day)

解析:

def parse_dates(content):
    dates = []
    for line in content:
        line_date = line.strip().split()
        dates.append(Date(line_date[0], line_date[1], line_date[2]))

    return dates

该文件被简单地打开,然后通过它返回一个日期对象列表

然后,将它传递给它以返回最早的日期:

def find_earliest(dates):
    return min(dates)
The file where the dates are retrieved from is shown above

解决 了我没有将日期转换为 int,因此它们保留为字符串,因此程序正在比较字符串而不是实际数值。我只是将所有内容都转换为 int 然后创建了日期对象。

标签: pythonpython-3.xlistclassobject

解决方案


int如果您不在Date构造函数中强制转换,则需要在解析中进行:

def parse_dates(content):
    dates = []
    for line in content:
        line_date = line.strip().split()
        dates.append(Date(*map(int, line_date)))

    return dates

或作为单行:

def parse_dates(content):
    return [Date(*map(int, line.strip().split())) for line in content]

如果您不想定义所有 dunder 比较方法,可以使用functools.total_ordering

from functools import total_ordering

@total_ordering
class Date(object):
    def __init__(self, year, month=1, day=1):
        #cast your values to ints
        self.year  = int(year)
        self.month = int(month)
        self.day   = int(day)

    def __str__(self):
        # using f-string and padding
        # to get "1994/02/07" instead of "1994/2/7"
        return f'{self.year}/{self.month:02}/{self.day:02}'

    def __eq__(self, other):
        return self.year  == other.year
           and self.month == other.month
           and self.day   == other.day

    def __lt__(self, other):
        # works because `or` short-circuits on first True
        return self.year  < other.year
            or self.month < other.month
            or self.day   < other.day

推荐阅读