Sort()

Bengt Richter bokr at oz.net
Thu Jun 5 14:26:08 EDT 2003


On Thu, 5 Jun 2003 11:42:07 -0500, sismex01 at hebmex.com wrote:

>> From: Turhan Ozen [mailto:txo at cs.nott.ac.uk]
>> Sent: Thursday, June 05, 2003 11:32 AM
>> 
>> I created a class and modified the default _comp_  function.  
>> I can sort an array of instances of this class. But I don't
>> want to change the original array. Instead, I want to keep
>> the positions after sorting in an attribute of the instances.
>> 
>> Instead of [a1,a2,a3] becoming [a2,a1,a3], I would like the 
>> order remain same but
>> 
>> a1.rank=2
>> a2.rank=1
>> a3.rank=3
>> 
>> How can I do this? Does this functionality already exist? If 
>> not could you please give me advice on how to implement it?
>> I have read the HOWTO on sorting, there is an example of sorting
>> classes there. Is there any other place where I can find more
>> examples of using Python functions?
>> 
>> Thanks,
>> Turhan.
>>
>
>Hmmm... you could simulate it with:
>
>## First we have...
>L = [ ... original list ... ]
>
>## Now, we create a sorted version of the list:
>SL = L[:]
>SL.sort()
>
>## We now create a dictionary keyed by item, relating to it's index:
>D = dict( zip(SL, range(len(SL))) )
>
>## And now, we transfer the index position as an attribute to
>## the items on the original list:
>for item in L:
>   item.rank = D[item]
>
Might be a problem if some objects are not hashable, or if they
hash to identical values (i.e., duplicates in list), so maybe

for i in xrange(len(SL)): setattr(SL[i], 'rank', i)

is safer. E.g.,

 >>> class X:
 ...     def __init__(self, v): self.v = v
 ...     def __cmp__(self,other): return cmp(self.v, other.v)
 ...     def __repr__(self): return '<X:%r>'%self.v
 ...
 >>> import random
 >>> L = [X(random.choice('abcdefg')) for i in xrange(8)]
 >>> L
 [<X:'a'>, <X:'a'>, <X:'b'>, <X:'c'>, <X:'b'>, <X:'g'>, <X:'g'>, <X:'d'>]
 >>> SL = L[:]
 >>> SL
 [<X:'a'>, <X:'a'>, <X:'b'>, <X:'c'>, <X:'b'>, <X:'g'>, <X:'g'>, <X:'d'>]
 >>> SL.sort()
 >>> SL
 [<X:'a'>, <X:'a'>, <X:'b'>, <X:'b'>, <X:'c'>, <X:'d'>, <X:'g'>, <X:'g'>]
 >>> L
 [<X:'a'>, <X:'a'>, <X:'b'>, <X:'c'>, <X:'b'>, <X:'g'>, <X:'g'>, <X:'d'>]
 >>> for i in xrange(len(SL)): setattr(SL[i],'rank',i)
 ...
 >>> L
 [<X:'a'>, <X:'a'>, <X:'b'>, <X:'c'>, <X:'b'>, <X:'g'>, <X:'g'>, <X:'d'>]
 >>> [x.rank for x in L]
 [0, 1, 2, 4, 3, 6, 7, 5]
 >>> [x.rank for x in SL]
 [0, 1, 2, 3, 4, 5, 6, 7]


Regards,
Bengt Richter




More information about the Python-list mailing list