>>> x = [4, 2, 1, 3] >>> y = [40, 200, 1, 30] >>> x_sorted, y_sorted = zip(*sorted(zip(x, y), key=lambda a:a[0])) >>> x_sorted (1, 2, 3, 4) >>> y_sorted (1, 200, 30, 40)
Performance:
>>> timeit('foo = zip(x,y); foo.sort(); zip(*foo)', 'from __main__ import x, y', number=1000) 1.0197240443760691 >>> timeit('zip(*sorted(zip(x,y)))', 'from __main__ import x, y', number=1000) 1.0106219310922597 >>> timeit('ind = range(1000); ind.sort(key=lambda i:x[i]); x_sorted = [x[i] for i in ind]; y_sorteds = [y[i] for i in ind]', 'from __main__ import x, y', number=1000) 0.9043525504607857 >>> timeit('zip(*sorted(zip(x, y), key=lambda a:a[0]))', 'from __main__ import x, y', number=1000) 0.8288150863453723
To see the full picture:
>>> timeit('sorted(x)', 'from __main__ import x, y', number=1000) 0.40415491505723367
@Falsetru method - fast for np.arrays
>>> timeit('order = np.argsort(x); x_sorted = x[order]; y_sorted = y[order]', 'from __main__ import x, y, np', number=1000) 0.05441799872323827
As @AshwiniChaudhary suggested in the comments for lists , there is a way to speed it up using itertools.izip instead of zip :
>>> timeit('zip(*sorted(izip(x, y), key=itemgetter(0)))', 'from __main__ import x, y;from operator import itemgetter;from itertools import izip', number=1000) 0.4265049757161705