Combined natural and unnatural list sorting
Peter Otten
__peter__ at web.de
Wed Jun 16 18:33:42 EDT 2004
Derek Basch wrote:
> I have a list like so:
>
> foo = ["White/M", "White/L", "White/XL", "White/S", "Black/S", "Black/M"]
> The order that I actually need is:
>
> ["White/S","White/M", "White/L", "White/XL", "Black/S", "Black/M"]
> I looked for a while at using comparison functions with sort but I don't
> think that will work. Anyone been down this road? Suggestions?
Here's a slightly more complicated approach. Turn what was the "unnatural"
into the "natural" order:
from itertools import count
class Size(object):
all = {}
_nextIndex = count().next
def __new__(cls, name):
try:
return cls.all[name]
except KeyError:
self = object.__new__(cls, name)
self.name = name
self.index = cls._nextIndex()
cls.all[name] = self
return self
def __init__(self, name):
pass
def __lt__(self, other):
return self.index < other.index
def __str__(self):
return self.name
for size in "XXS XS S M L XL XXL".split():
Size(size)
del size
class TShirt(object):
def __init__(self, colorSize):
self.color, size = colorSize.split("/")
self.size = Size(size)
def __lt__(self, other):
if self.color == other.color:
return self.size < other.size
return self.color < other.color
def __str__(self):
return "%s/%s" % (self.color, self.size)
stock = map(TShirt, ["White/M", "White/L", "White/XL", "White/S", "Black/S",
"Black/M"])
# color, size
stock.sort()
for tshirt in stock:
print tshirt
print "---"
# size, color
stock.sort(lambda s, t: cmp(s.size, t.size) or cmp(s.color, t.color))
for tshirt in stock:
print tshirt
Peter
More information about the Python-list
mailing list