sort descending on a[1], ascending on a[0]
Manuel M. Garcia
mgarcia at cole-switches.com
Thu Oct 10 16:36:23 EDT 2002
t = """
jsaul asked a question about a custom sort, which reminded me of a
problem I often have with sorting.
What is everyones favorite way of sorting descending on a[1], and
ascending on a[0]? (or however you wish, even changing this on
the fly)
I am not a big fan of passing sort() a comparison function, but I
don't see how I could use the Decorate - Sort - Undecorate (DSU)
technique.
Below is how I usually do it, and also a more general method that
generates the function for sort() that lets you choose
the order of the indexes and whether you sort ascending or
descending for each index.
b b b b b b b b h h h h h descending comparison aaaaaaaaaa
"""
import re
t = re.sub(r'[^a-z]+',' ',t.lower()).strip()
d = {}
for w in t.split(' '):
d[w] = d.get(w,0) + 1
def sort_f(a,b):
if a[1] != b[1]:
return -cmp(a[1],b[1])
else:
return cmp(a[0],b[0])
list0 = d.items()
list0.sort(sort_f)
print '* sort by a[1](desc) then a[0]'
for a in list0[:10]: print a
# very clean with lexically nested scopes (Python 2.2)
def make_sort_f(list0):
def f(a,b):
for (i,m) in list0:
if a[i] == b[i]: continue
return m * cmp(a[i],b[i])
return 0
return f
list1 = [ (w,c,len(w)) for (w,c) in d.items() ]
list1.sort(make_sort_f( [(2,-1),(1,-1),(0,1)] ))
print '* sort by a[2](desc) then a[1](desc) then a[0]'
for a in list1[:10]: print a
----------(output)-----------
* sort by a[1](desc) then a[0]
('a', 8)
('b', 8)
('h', 5)
('i', 5)
('sort', 5)
('the', 5)
('of', 4)
('and', 3)
('descending', 3)
('on', 3)
* sort by a[2](desc) then a[1](desc) then a[0]
('descending', 3, 10)
('comparison', 2, 10)
('aaaaaaaaaa', 1, 10)
('undecorate', 1, 10)
('ascending', 2, 9)
('everyones', 1, 9)
('generates', 1, 9)
('technique', 1, 9)
('function', 2, 8)
('changing', 1, 8)
More information about the Python-list
mailing list