sort one list using the values from another list

bearophileHUGS at lycos.com bearophileHUGS at lycos.com
Sun Feb 26 14:10:38 EST 2006


Your solution Steven Bethard looks very intelligent, here is a small
speed test, because sorting a list according another one is a quite
common operation.
(Not all solutions are really the same, as Alex has shown).


from itertools import izip, imap
from operator import itemgetter
from random import randint, choice, randint, shuffle
from string import lowercase

def timeit(function, *arg1, **arg2):
    """timeit(function, *arg1, **arg2): given a function and its
parameters, calls it
    and computes its running time, in seconds. It result is
discarded."""
    t1 = clock()
    function(*arg1, **arg2)
    t2 = clock()
    return round(t2-t1, 2)

def psort1(s1, s2):
    s1[:] = [a for b,a in sorted(zip(s2, s1))]

def psort2(s1, s2):
    aux = zip(s2, enumerate(s1))
    aux.sort()
    s1[:] = [a for b, (i, a) in aux]

def psort3(s1, s2):
    _indices = range(len(s1))
    _indices.sort(key=s2.__getitem__)
    s1[:] = [s1[i] for i in _indices]

def psort4(s1, s2):
    _indices = range(len(s1))
    _indices.sort(key=s2.__getitem__)
    s1[:] = map(s1.__getitem__, _indices)

def psort5(s1, s2):
    s1[:] = zip(*sorted(zip(s2, s1)))[1]

def psort6(s1, s2):
    s1[:] = map(itemgetter(0), sorted(zip(s1, s2), key=itemgetter(1)))

def psort7(s1, s2):
    s1[:] = [a for b,a in sorted(izip(s2, s1))]

def psort8(s1, s2):
    s1[:] = zip(*sorted(izip(s2, s1)))[1]

def psort9(s1, s2):
    s1[:] = map(itemgetter(0), sorted(izip(s1, s2), key=itemgetter(1)))


n = 100000
s1 = ["".join(choice(lowercase) for i in xrange(randint(2,8))) for k in
xrange(n)]
s2 = range(n)
shuffle(s2)

for psort in sorts:
    s1c = list(s1)
    print timeit(psort, s1c, s2), "s"


Timings on my PC, Python 2.4, PIII 500 MHz:
2.87
3.82
1.6
1.56
4.35
2.49
2.75
4.29
2.35

psort4 is my variant of your solution, and it seems the faster one.
Note: one liners are bad, and expecially bad in Python that is designed
to be a readable language, so let's avoid them as much as possible. I
have used one of them to generate s1, but I'll not use them in
production code or in my libraries, etc.

Bye,
bearophile




More information about the Python-list mailing list