[Tutor] Sort pointers -

Brian van den Broek bvande at po-box.mcgill.ca
Wed Nov 24 17:30:15 CET 2004


Kent Johnson said unto the world upon 2004-11-24 06:05:

<SNIP helpful explanations>

> 
> In Python 2.3 you have two choices:
> - Use the decorate - sort - undecorate idiom (aka Schwartzian Transform)
> - Define your own comparison function
> 
> I'm out of time for explaining right now, maybe someone else can pick up 
> the thread or I'll come back to it later...
> 
> Kent
> 
> Liam Clarke wrote:
> 
>> Kia ora,
>>
>> Just exploring the wonderful world of dictionaries, and I'm trying to
>> comprehend the sort() method, because as I found, dictionaries are not
>> sorted.
>>

<SNIP examples from question>

>> That's just an example of output. I'm not too hung up on the output at
>> the moment, just sort().
>>
>> It says to use a comparison function...
>>
>> And I have no idea how to work that.
>>
>> ??? Very confused. I've tried searching for info, there's some very
>> complex ways out there to sort data, usually with proper first names
>> (Schwartzian transformations...), but I can't seem to find the simple.
>>
>> Could anyone post some useful links for my education?
>>
>> Much appreciated.
>>
>> Liam Clarke

Hi Liam,

maybe this will help:

 >>> def length_sort(first, second):
     '''A custom cmp function to pass to sort for sort on item length'''
     # We do a standard sort of the length of the items compared.
     return cmp(len(first), len(second))

 >>> def alphabetical_sort(first, second):
     '''A custom cmp function to pass to sort for case insensitive sort'''
     first = first.lower()
     second = second.lower()
     # We do a standard sort on lower-cased versions of the items
     # compared.
     return cmp(first, second)

a_list = ['BC', 'def', 'GHIJ', 'a', 'kH', 'AH']
 >>> print a_list.sort()
None
 >>> # sort modifies in place, so printing a_list.sort() gives None
 >>> # Probably not what was wanted!
 >>>
 >>> a_list.sort()
 >>> print a_list
['AH', 'BC', 'GHIJ', 'a', 'def', 'kH']
 >>> # quite likely not what is wanted either, as all CAP letters come
 >>> # before lower-case when the standard cmp(x,y) function is used.
 >>>
 >>> a_list.sort(alphabetical_sort)
 >>> print a_list
['a', 'AH', 'BC', 'def', 'GHIJ', 'kH']
 >>> # now, via alphabetical_sort(), it is sorted in true alpha-order
 >>>
 >>> a_list.sort(length_sort)
 >>> print a_list
['a', 'AH', 'BC', 'kH', 'def', 'GHIJ']
 >>> # Since length_sort only cares about the len of an object, for
 >>> # any two string of equal length, it leaves their order unchanged
 >>> # from the way it was before the list was sorted.
 >>>
 >>> # Now let's try something a bit silly:
 >>> def goofy_H_sort(first, second):
     '''A custom cmp function to pass to sort for 'H'-based sorting'''
     if 'H' in first and 'H' not in second:
         return first, second
     if 'H' in second and 'H' not in first:
         return second, first
     return cmp(first, second)

 >>> a_list.sort(goofy_H_sort)

Traceback (most recent call last):
   File "<pyshell#76>", line 1, in -toplevel-
     a_list.sort(goofy_H_sort)
TypeError: comparison function must return int
 >>>
 >>> # Well, that didn't work! Checking section 2.1 of the Lib Ref
 >>> # for the cmp(x,y) built-in suggests we do:
 >>> def goofy_H_sort(first, second):
     '''A custom cmp function to pass to sort for 'H'-based sorting'''
     if 'H' in first and 'H' not in second:
         return -1
         # cmp(x,y)'s way of saying x < y, so by returning -1, we
         # model that behaviour and have our custom sort function
         # say that first comes before second.
     if 'H' in second and 'H' not in first:
         return 1
         # cmp(x,y)'s way of saying x > y, so by returning 1, we
         # model that behaviour and have our custom sort function
         # say that first comes after second.
     return cmp(first, second)

 >>> a_list.sort(goofy_H_sort)
 >>> print a_list
['AH', 'GHIJ', 'kH', 'BC', 'a', 'def']
 >>>

HTH,

Brian vdB




More information about the Tutor mailing list