cmp(a, b) returns:
- -1, if a < b
- 0 if a == b
- 1 if a > b
Every time I create a class that needs a __cmp__, I'm tempted to go scrambling to the Python docs for a refresher on what the three return values of cmp mean. But really, there is no need to worry about this. You can simply use the cmp() function to do it for you.
I'll demonstrate with an example:
Ultra Verbose Way
#
# I'm going to make a list of people. For each person I will
# store their first and last name, and the state they live in.
#
# For sorting, I want to sort FIRST by state, SECOND by last name,
# and finally by first name.
#
class Person(object):
def __init__(self, first, last, state):
self.first = first
self.last = last
self.state = state
# define __str__ so that 'print object' will look good
def __str__(self):
return "%s: %s, %s" % (self.state, self.last, self.first)
# naive __cmp__, where I have to remember what -1, 0, and 1 mean.
def __cmp__(self, other):
# sort first by state
if self.state < other.state:
return -1
elif self.state > other.state:
return 1
else:
# state is equal, - sort by last name
if self.last < other.last:
return -1
elif self.last > other.last:
return 1
else:
# state and last name are equal,
# sort by first name
if self.first < other.first:
return -1
elif self.first > other.first:
return 1
else:
return 0
def show(people):
for p in people:
print p
people = [
Person("Tom","Zeelman",'MN'),
Person("Ozlo","Yannican",'AZ'),
Person("Mike","Dodger",'AL'),
Person("Greta","Abington",'CT'),
Person("Ooolma", "Therrmon",'MS'),
Person("Bob","Abington",'AL'),
Person("Erma","Valencio",'AZ'),
Person("Abe","Abington",'CT'),
Person("Zeldo","Yannican",'TN'),
]
print "Original list:"
print "--------------"
show(people)
people.sort()
print "
Sorted:"
print "--------"
show(people)
# I'm going to make a list of people. For each person I will
# store their first and last name, and the state they live in.
#
# For sorting, I want to sort FIRST by state, SECOND by last name,
# and finally by first name.
#
class Person(object):
def __init__(self, first, last, state):
self.first = first
self.last = last
self.state = state
# define __str__ so that 'print object' will look good
def __str__(self):
return "%s: %s, %s" % (self.state, self.last, self.first)
# naive __cmp__, where I have to remember what -1, 0, and 1 mean.
def __cmp__(self, other):
# sort first by state
if self.state < other.state:
return -1
elif self.state > other.state:
return 1
else:
# state is equal, - sort by last name
if self.last < other.last:
return -1
elif self.last > other.last:
return 1
else:
# state and last name are equal,
# sort by first name
if self.first < other.first:
return -1
elif self.first > other.first:
return 1
else:
return 0
def show(people):
for p in people:
print p
people = [
Person("Tom","Zeelman",'MN'),
Person("Ozlo","Yannican",'AZ'),
Person("Mike","Dodger",'AL'),
Person("Greta","Abington",'CT'),
Person("Ooolma", "Therrmon",'MS'),
Person("Bob","Abington",'AL'),
Person("Erma","Valencio",'AZ'),
Person("Abe","Abington",'CT'),
Person("Zeldo","Yannican",'TN'),
]
print "Original list:"
print "--------------"
show(people)
people.sort()
print "
Sorted:"
print "--------"
show(people)
Much better __cmp__
#
# I'm going to make a list of people. For each person I will
# store their first and last name, and the state they live in.
#
# For sorting, I want to sort FIRST by state, SECOND by last name,
# and finally by first name.
#
class Person(object):
def __init__(self, first, last, state):
self.first = first
self.last = last
self.state = state
# define __str__ so that 'print object' will look good
def __str__(self):
return "%s: %s, %s" % (self.state, self.last, self.first)
# much better - I don't care what -1, 0 and 1 mean.
# due to boolean short-circuit logic, the "or" sequence will
# return the cmp() value of the first non-equal piece
def __cmp__(self, other):
return cmp(self.state, other.state,) or
cmp(self.last,other.last) or
cmp(self.first,other.first)
def show(people):
for p in people:
print p
people = [
Person("Tom","Zeelman",'MN'),
Person("Ozlo","Yannican",'AZ'),
Person("Mike","Dodger",'AL'),
Person("Greta","Abington",'CT'),
Person("Ooolma", "Therrmon",'MS'),
Person("Bob","Abington",'AL'),
Person("Erma","Valencio",'AZ'),
Person("Abe","Abington",'CT'),
Person("Zeldo","Yannican",'TN'),
]
print "Original list:"
show(people)
people.sort()
print "
Sorted:"
show(people)
# I'm going to make a list of people. For each person I will
# store their first and last name, and the state they live in.
#
# For sorting, I want to sort FIRST by state, SECOND by last name,
# and finally by first name.
#
class Person(object):
def __init__(self, first, last, state):
self.first = first
self.last = last
self.state = state
# define __str__ so that 'print object' will look good
def __str__(self):
return "%s: %s, %s" % (self.state, self.last, self.first)
# much better - I don't care what -1, 0 and 1 mean.
# due to boolean short-circuit logic, the "or" sequence will
# return the cmp() value of the first non-equal piece
def __cmp__(self, other):
return cmp(self.state, other.state,) or
cmp(self.last,other.last) or
cmp(self.first,other.first)
def show(people):
for p in people:
print p
people = [
Person("Tom","Zeelman",'MN'),
Person("Ozlo","Yannican",'AZ'),
Person("Mike","Dodger",'AL'),
Person("Greta","Abington",'CT'),
Person("Ooolma", "Therrmon",'MS'),
Person("Bob","Abington",'AL'),
Person("Erma","Valencio",'AZ'),
Person("Abe","Abington",'CT'),
Person("Zeldo","Yannican",'TN'),
]
print "Original list:"
show(people)
people.sort()
print "
Sorted:"
show(people)
Written in WikklyText.

Comments
return cmp(self.state,
cmp(self.last,other.last) or
cmp(self.first,other.first)
(other.state, other.last, other.first))
Good point, thanks. For some
Good point, thanks. For some reason I've never liked comparing tuples ... my C/C++ upbringing is holding me back again :-)
Post new comment