How do I sort these?

Bengt Richter bokr at oz.net
Sun Oct 30 03:27:45 CET 2005


On Fri, 28 Oct 2005 20:00:42 +0100, Steve Holden <steve at holdenweb.com> wrote:

>KraftDiner wrote:
>> I have two lists.
>> I want to sort by a value in the first list and have the second list
>> sorted as well... Any suggestions on how I should/could do this?
>> 
> >>> first = [1, 3, 5, 7, 9, 2, 4, 6, 8]
> >>> second = ['one', 'three', 'five', 'seven', 'nine', 'two', 'four', 
>'six', 'eight']
> >>> both = zip(first, second)
> >>> both.sort()
> >>> [b[0] for b in both]
>[1, 2, 3, 4, 5, 6, 7, 8, 9]
> >>> [b[1] for b in both]
>['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
> >>>
>
>You mean like this?
ISTM there could be a subtle requirement in the way the OP stated what he wanted to do.
I.e., it sounds like he would like to sort the first list and have a second list undergo
the same shuffling as was required to sort the first. That's different from having the
data of the second participate in the sort as order-determining data, if equals in the
first list are not to be re-ordered:

 >>> first = [2]*5 + [1]*5
 >>> first
 [2, 2, 2, 2, 2, 1, 1, 1, 1, 1]
 >>> sorted(first)
 [1, 1, 1, 1, 1, 2, 2, 2, 2, 2]
 >>> second = [chr(ord('A')+i) for i in xrange(9,-1,-1)]
 >>> second
 ['J', 'I', 'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A']
 >>> sorted(second)
 ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']

Now the zipped sort unzipped:
 >>> zip(*sorted(zip(first,second)))
 [(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J')]

Now suppose we sort the first and use the elements' indices to preserve order where equal
 >>> sorted((f,i) for i,f in enumerate(first))
 [(1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4)]

Separate out the first list elements:
 >>> [t[0] for t in sorted((f,i) for i,f in enumerate(first))]
 [1, 1, 1, 1, 1, 2, 2, 2, 2, 2]

Now select from the second list, by first-element position correspondence:
 >>> [second[t[1]] for t in sorted((f,i) for i,f in enumerate(first))]
 ['E', 'D', 'C', 'B', 'A', 'J', 'I', 'H', 'G', 'F']

Which did the OP really want? ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list