DSU pattern (was Re: Trouble sorting lists (unicode/locale related?))

Duncan Booth duncan at NOSPAMrcp.co.uk
Mon Sep 22 16:09:06 CEST 2003


Alex Martelli <aleax at aleax.it> wrote in
news:DUCbb.100826$hE5.3550910 at news1.tin.it: 

>> So maybe it's about time to change the sort() method to support a
>> second argument
>> 
>> list.sort(compare=None, mapping=None)
>> 
>> that, if provided, would perform the DSU magic. Or was that already
>> proposed and rejected?
> 
> I have not seen this proposed before, and I'm not very clear on what
> the "compare" and "mapping" arguments are supposed to be in order to
> let you specify any DSU.  Basically it seems you would need two
> callables, "decorate" to be called with each item in the list (to
> return for each item the decorated tuple) and "undecorate" to be
> called with each decorated tuple after the sort (to return the item
> for the result).  How do you turn that into "compare" and "mapping"?
> 
> 
You don't need two callables because the sort function would be doing
the decorating, so it knows also how to undecorate. I think the
suggestion is that the mapping argument returns something that can be
compared. 

For example, here is a DSU function that does a not-in-place sort and
takes a suitable mapping argument. Changing it to in-place sort is,
of course, trivial. 

>>> def DSU(aList, aMapping):
	newList = [ (aMapping(item), index, item) for (index, item)
		    in enumerate(aList) ]
	newList.sort()
	return [ item[2] for item in newList ]

>>> print DSU(['Alex Martelli', 'Duncan Booth', 'Peter Otten', 'Jeff Epler'], 
       str.lower)
['Alex Martelli', 'Duncan Booth', 'Jeff Epler', 'Peter Otten']
>>> def lastFirst(name):
	names = name.split()
	names = names[-1:] + names[:-1]
	return [name.lower() for name in names]

>>> print DSU(['Alex Martelli', 'Duncan Booth', 'Peter Otten', 'Jeff Epler'], 
       lastFirst)
['Duncan Booth', 'Jeff Epler', 'Alex Martelli', 'Peter Otten']


-- 
Duncan Booth                                            
duncan at rcp.co.uk int month(char
*p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3" 
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure? 




More information about the Python-list mailing list