基于对象的属性(甚至是NoneType)对Python中的对象列表进行排序

时间:2016-03-17 16:39:08

标签: python list sorting object

我有发票清单,其中包括发票对象。 我想根据日期和下面的顺序订购这些对象。

from operator import attrgetter
invoices_list.sort(key=attrgetter('date'))

这是我得到的错误。

TypeError: can't compare FakeDatetime to NoneType

我想按照日期按升序排列对象,无日期应该是第一个。然后其他人应该按升序排列。

$ invoices_list[0].date
$ FakeDatetime(2015, 7, 3, 0, 0)

4 个答案:

答案 0 :(得分:1)

一个简单的密钥包装器可以完成这项工作:

<!DOCTYPE html>
<html>
  <head>
    <title>asd</title>
  </head>
  <body>
    <application></application>
  </body>
  <script src="/bundle.js"></script>
</html>

然后使用它:

class DateKey(object):
    def __init__(self, invoice):
        self.value = invoice.date
    def __lt__(self, other):
        if not isinstance(other, (datetime.date, type(None))):
            return NotImplemented
        elif self.value is None:
            return True
        elif other.value is None:
            return False
        else:
            return self.value < other.value

答案 1 :(得分:0)

编写一个自定义比较函数,该函数知道如何比较FakeDateTimeNone个对象,然后通过指定sort()关键字参数告诉cmp使用此函数。

答案 2 :(得分:0)

如果您有一些默认值(例如0),您可以执行以下操作:

invoices_list.sort(key=lambda invoice: invoice.get('date') if (invoice != None) else 0)

答案 3 :(得分:0)

由于您尚未指定FakeDatetime的结构,我将尝试使用内置的datetime模块解决您的问题。

基本上,即使dateNone,您也希望对列表进行排序。为此,您必须在获得None日期时使用默认值。因此,在我的解决方案中,当我获得None日期时,我将最小可能日期作为默认值。因此,具有None日期的所有元素都将放在排序列表的顶部。

import datetime

def get_key(d):
    return d.date if hasattr(d, 'date') and d.date is not None else datetime.date(datetime.MINYEAR, 1, 1)

sorted(invoices_list, key=get_key)