Velocity Reviews > problem with custom sort function .... long

# problem with custom sort function .... long

Ken R.
Guest
Posts: n/a

 08-21-2003
Hello all,
I am relatively new to python but I am having an issue with custom
sort functions..

I am trying to sort a list of lists or tuples with arbitrary ascending
or descending sorts. For example given a list of tuples
('firstname','lastname','age') I want to be able to sort lastname
descending, firstname ascending and age ascending...

I wrote a custom function generator to generate a sort function based
on an input list of column numbers and sort direction. Sort seems to
sort the first column ascending regardless of what the sort function
says. I also googled this group for other solutions and found a more
elegant one than mine but with the same results.

Here is my code and result:
sortList = [('2','D'),('1','D'),('0','D')]
dataList = []
dataList.append(['a','a','b'])
dataList.append(['a','a','a'])
dataList.append(['a','a','c'])
dataList.append(['a','b','a'])
dataList.append(['a','b','b'])
dataList.append(['a','b','c'])
dataList.append(['a','c','a'])
dataList.append(['a','c','b'])

outStr = 'def custSort( a, b):\n'
depth = 1

for sortPair in sortList:
indent = " "
curDent = depth * indent
outStr += curDent + 'if a[' + sortPair[0] + '] == b[' +
sortPair[0] + ']:\n'
depth += 1

depth -= 1
outStr += curDent + indent + 'return 0\n'
for j in range( len(sortList)-1, -1, -1 ):
curDent = depth * indent
print sortList[j][1]
if sortList[j][1] == 'A':
compareSym = '>'
elif sortList[j][1] == 'D':
compareSym = '<'
else:
print 'SORT DIRECTION ERROR ' + sortList[j][1]
outStr += curDent + 'elif a[' + sortList[j][0] + '] ' + compareSym
+ ' b[' + sortList[j][0] + ']:\n'
outStr += curDent + indent + 'return 1\n'
outStr += curDent + 'else:\n'
outStr += curDent + indent + 'return -1\n'
depth -= 1

print outStr
exec( outStr )
dataList.sort( custSort )
print str( dataList )

***************************
results:
D
D
D
def custSort( a, b):
if a[2] == b[2]:
if a[1] == b[1]:
if a[0] == b[0]:
return 0
elif a[0] < b[0]:
return 1
else:
return -1
elif a[1] < b[1]:
return 1
else:
return -1
elif a[2] < b[2]:
return 1
else:
return -1

[['a', 'b', 'c'], ['a', 'a', 'c'], ['a', 'c', 'b'], ['a', 'b', 'b'],
['a', 'a', 'b'], ['a', 'c', 'a'], ['a', 'b', 'a'], ['a', 'a', 'a']]

and Manuel Garcia's solution and results:
sortList = [(0,-1),(1,-1),(2,-1)]
dataList = []
dataList.append(['a','a','b'])
dataList.append(['a','a','a'])
dataList.append(['a','a','c'])
dataList.append(['a','b','a'])
dataList.append(['a','b','b'])
dataList.append(['a','b','c'])
dataList.append(['a','c','a'])
dataList.append(['a','c','b'])

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

dataList.sort( make_sort_f( sortList ) )
print str(dataList)

Results:
[['a', 'c', 'b'], ['a', 'c', 'a'], ['a', 'b', 'c'], ['a', 'b', 'b'],
['a', 'b', 'a'], ['a', 'a', 'c'], ['a', 'a', 'b'], ['a', 'a', 'a']]

is this an issue with sort or is my code screwy? Thanks in advance
for any help!

Ken R.

Terry Reedy
Guest
Posts: n/a

 08-22-2003

"Ken R." <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) m...
> Hello all,
> I am relatively new to python but I am having an issue with custom
> sort functions..

Athough they seem to be working fine!

> I am trying to sort a list of lists or tuples with arbitrary

ascending
> or descending sorts. For example given a list of tuples
> ('firstname','lastname','age') I want to be able to sort lastname
> descending, firstname ascending and age ascending...
>
> I wrote a custom function generator to generate a sort function

based
> on an input list of column numbers and sort direction. Sort seems to
> sort the first column ascending regardless of what the sort function
> says. I also googled this group for other solutions and found a

more
> elegant one than mine but with the same results.

Given that your example data all have 'a' in the first column, these
statements of ill behavior make no sense!

> Here is my code and result:
> sortList = [('2','D'),('1','D'),('0','D')]
> dataList = []
> dataList.append(['a','a','b'])
> dataList.append(['a','a','a'])
> dataList.append(['a','a','c'])
> dataList.append(['a','b','a'])
> dataList.append(['a','b','b'])
> dataList.append(['a','b','c'])
> dataList.append(['a','c','a'])
> dataList.append(['a','c','b'])

You could just as well write dataList as a single literal.

[snip]

> [['a', 'b', 'c'], ['a', 'a', 'c'], ['a', 'c', 'b'], ['a', 'b', 'b'],
> ['a', 'a', 'b'], ['a', 'c', 'a'], ['a', 'b', 'a'], ['a', 'a', 'a']]

and columns 2, 1, and 0 are descending (non-increasing) in that order,
just as you asked. What different were you expecting given the input.

> and Manuel Garcia's solution and results:
> sortList = [(0,-1),(1,-1),(2,-1)]

....
> Results:
> [['a', 'c', 'b'], ['a', 'c', 'a'], ['a', 'b', 'c'], ['a', 'b', 'b'],
> ['a', 'b', 'a'], ['a', 'a', 'c'], ['a', 'a', 'b'], ['a', 'a', 'a']]

Again, just as requested. Same question.

> is this an issue with sort or is my code screwy?

Perhaps your understanding of ascending and descending? or of nested
sorting?

Terry J. Reedy

Ken R.
Guest
Posts: n/a

 08-22-2003
> Given that your example data all have 'a' in the first column, these
> statements of ill behavior make no sense!
>

Oh my! One would think that I just dashed off a question to the group
without spending any time on the problem (not the case). No excuses