What is the best way to sort items on one of the items values
I have two instances of an object in a list
class Thing():
timeTo = 0
timeFrom = 0
name = ""
o1 = Thing()
o1.name = "One"
o1.timeF开发者_Python百科rom = 2
o2 = Thing()
o2.timeTo = 20
o2.name = "Two"
myList = [o1, o2]
biggestIndex = (myList[0].timeFrom < myList[1].timeTo) & 1
bigger = myList.pop(biggestIndex)
lesser = myList.pop()
print bigger.name
print lesser.name
both o1 and o2 have two properties that I want to compare the first in the lists timeFrom property and the second ones timeTo property to eachother.
I feel this is a bit awkward and wierd, is there perhaps a better and more readable approach to this?
The best solution is to make Thing
instances sortable. You do this by implementing __lt__
:
class Thing():
timeTo = 0
timeFrom = 0
name = ""
def __lt__(self, other):
return self.timeFrom < other.timeTo
lesser, bigger = sorted(myList)
Python2 has lesser, bigger = sorted(myList, cmp=lambda one,other: one.timeFrom < other.timeTo)
.
In Python3 cmp
is gone, I guess to force people to do (or learn) OOP and write a adapter.
class SortAdaper(object):
def __init__(self, obj ):
self.obj = obj
class TimeLineSorter(SortAdaper):
""" sorts in a timeline """
def __lt__(self, other):
return self.obj.timeFrom < other.obj.timeTo
class NameSorter(SortAdaper):
""" sorts by name """
def __lt__(self, other):
return self.obj.name < other.obj.name
print sorted( myList, key=TimeLineSorter)
print sorted( myList, key=NameSorter)
see attrgetter
import operator
getter = operator.attrgetter('timeFrom')
bigger = max(myList, key=getter)
lesser = min(myList, key=getter)
print bigger.name
print lesser.name
EDIT :
attrgetter also wokrs with sorted or anywhere a key function is needed.
lesser, bigger = sorted(myList, key=getter)
I would do this, if object can have only one of the time values:
class Thing(object):
def __init__(self, name, time = 0, timename = 'to'):
self.name, self.time, self.timename = (name,time,timename)
def __repr__(self):
return "Thing(%r, %i, %r)" % (self.name, self.time, self.timename)
def __lt__(self, other):
return self.time < other.time
o1 = Thing("One", 5, 'from')
o2 = Thing("Two", 20, 'to')
myList = [o1, o2]
print myList
print max(myList)
print min(myList)
精彩评论