[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