# Combined natural and unnatural list sorting

Thorsten Kampe thorsten at thorstenkampe.de
Wed Jun 16 23:31:50 CEST 2004

```* Derek Basch (2004-06-15 23:38 +0100)
> Hello All,
>
> I need to sort a list using an unnatural sequence.
>
> I have a list like so:
>
> foo = ["White/M", "White/L", "White/XL", "White/S", "Black/S", "Black/M"]
>
> print foo.sort()
>
> ['White/L', 'White/M', 'White/S', 'White/XL', 'Black/M', 'Black/S']
>
> The order that I actually need is:
>
> ["White/S","White/M", "White/L", "White/XL", "Black/S", "Black/M"]
>
> So, in other words, I need the colors sorted alphabetically and the the sizes
> sorted logically.
>
> 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?

You need some kind of general "function sort" (either using the
"Decorate, Sort, Undecorate" or the "pass a function" idiom):

def funcsort(seq, function, modus = 'dsu'):
"""
sort seq by function(item)
"""

if   modus == 'dsu':
seq = [(function(item), index, item) for index, item in enumerate(seq)]
seq.sort()
return [item[2] for item in seq]
elif modus == 'pass':
seq = seq[:]
seq.sort(lambda x, y: cmp(function(x), function(y)))
return seq

This is a common kind of sort problem so you will need this "function
sort" anyway in near future.

Then your problem simply translates to find a function that generates
your sort items like you want them sorted (in this case something like
'White/M' -> ('White', 2) ):

SIZE_MAP = {'S':  1,
'M':  2,
'L':  3,
'XL': 4}

def func(item):
splititem = item.split('/')
return splititem[0], SIZE_MAP[splititem[1]]

print funcsort(foo, func)

Thorsten

```