【问题标题】:Custom __lt__ method for comparisons用于比较的自定义 __lt__ 方法
【发布时间】:2017-02-18 00:23:49
【问题描述】:

我希望能够按一个属性对类列表进行排序,该属性恰好是另一个类 Date。我做了一些研究,想使用sorted(list, key=lambda x:date) 排序方法,但是看到日期本身就是一个类,我如何在日期中编写__lt__ 函数以允许我按时间顺序排序?

我想要一些类似的东西:

if self.year!= other.year:
    return self.year < other.year
elif self.month != pther.month
...

等等。

这是我的 Date 类:

class Date:
    def __init__(self, month, day, year, minute, hour, string):
        self.month = month
        self.day = day
        self.year = year
        self.minute = minute
        self.hour = hour
        self.string = string

我应该提一下,这是我第一次使用 Python,所以我不太擅长。

提前致谢!

【问题讨论】:

  • 你的意思是对象列表吗?
  • 只是好奇:为什么要这样存储日期而不是使用内置日期?
  • @Sebastian Wozny 抱歉,是的,我指的是对象
  • 如果你真的想要这样的东西,我认为你走在了一个很好的轨道上。为什么不写呢?
  • @SebastianWozny 我在语法上遇到了更多问题。您是否继续将我在那里的内容写入__lt__ 函数?当我调用 sorted 时会对其进行排序?

标签: python list sorting


【解决方案1】:

比较两个复杂数据结构的简单方法是以正确的排序顺序比较它们的属性元组。试试这个:

class Date:
    def __init__(self, month, day, year, minute, hour, string):
        self.month = month
        self.day = day
        self.year = year
        self.minute = minute
        self.hour = hour
        self.string = string
    def __lt__(self, other):
        return (self.year, self.month, self.day, self.hour, self.minute) < \
               (other.year, other.month, other.day, other.hour, other.minute)

assert Date(4, 15, 2016, 30, 12, '') < \
       Date(4, 16, 2016, 0, 0, '') < \
       Date (1, 1, 2017, 59, 23, '')

assert not (Date(4, 16, 2016, 0, 0, '') < Date(4, 15, 2016, 30, 12, ''))

当然,这只实现了&lt;。根据代码的性质,您可能希望实现所有其他比较函数,&gt;==!= 等。一种方便的方法是使用 @functools.total_ordering 类装饰器。

参考:

【讨论】:

  • 我认为你需要括号。
  • 具体在哪里?你为什么这么认为?
  • 围绕你的元组。 &lt; 的优先级高于逗号,因此您实际上返回的不是布尔值,而是一个 9 元素元组,中间有一个 self.minute &lt; other.year 布尔值。
  • 另外,最好实现 __eq__ 并将 functools.total_ordering 放在此类上以获取其余的比较方法,或者至少提到记住它们很重要真实代码。
  • @user2357112 - 同意。
【解决方案2】:

我建议在类定义中添加一个datetime 对象:

import datetime as dt, operator as op

class MyDate(object):
    def __init__(self, month, day, year, minute, hour, string):
        self.month = month
        self.day = day
        self.year = year
        self.minute = minute
        self.hour = hour
        self.string = string
        self.dt = dt.datetime(self.year,self.month,self.day,self.hour,self.minute)

l = []
l.append(MyDate(2,17,2017,33,16,'somestring')) # not sure what `string` should be
l.append(MyDate(2,17,2017,37,16,'anotherstring'))
l.append(MyDate(2,17,2017,38,16,'yetanotherstring'))

然后你可以使用operator.attgetter进行排序,例如:

>>> sorted(l,key=op.attrgetter('dt'),reverse=True)
[<__main__.MyDate object at 0x000000000A4C84A8>, 
 <__main__.MyDate object at 0x000000000A4C8208>, 
 <__main__.MyDate object at 0x000000000A4C8978>]

【讨论】:

    猜你喜欢
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多