Reputation: 99
I want to be able to sort a list of classes by one attribute, which happens to be another class Date. I have done some research and want to use the sorted(list, key=lambda x:date)
method of sorting, but seeing as date is a class in itself how can I write an __lt__
function in date to allow me to sort chronologically?
I want something along the lines of:
if self.year!= other.year:
return self.year < other.year
elif self.month != pther.month
...
and so on.
Here is my Date class:
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
I should probably mention that this is the first time I have ever used Python, so I'm not very good at this.
Thanks in advance!
Upvotes: 4
Views: 4295
Reputation: 168736
The easy way to compare two complex data structures is to compare tuples of their attributes, in the proper sort order. Try this:
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, ''))
Of course, this only implements <
. Depending upon the nature of your code, you may want to implement all of the other comparison functions, >
, ==
, !=
, etc. One convenient way to do this is to use the @functools.total_ordering
class decorator.
Reference:
Upvotes: 5
Reputation: 169444
I propose adding a datetime
object to the class definition:
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'))
Then you can use operator.attgetter
to sort, e.g.:
>>> sorted(l,key=op.attrgetter('dt'),reverse=True)
[<__main__.MyDate object at 0x000000000A4C84A8>,
<__main__.MyDate object at 0x000000000A4C8208>,
<__main__.MyDate object at 0x000000000A4C8978>]
Upvotes: 1