4
\$\begingroup\$

This sorts two lists (a, b) according to aand returns two sorted lists separately:

a = ['apple','carrot','banana']
b = [5,15,10]

s = sorted(zip(a,b))
a,b = map(list, zip(*s))

print a
print b

['apple', 'banana', 'carrot']
[5, 10, 15]

Are there any better ways to do this?

\$\endgroup\$
3
\$\begingroup\$

It depends on what do you understand by better ways to do this. Your approach is the usual way of sorting two lists in Python. But there are, of course, multiple methods which may serve different purposes depending on list length for example.

Different ways below:

>>> list1 = [3,2,4,1,1]
>>> list2 = ['three', 'two', 'four', 'one', 'one2']
>>> list1, list2 = zip(*sorted(zip(list1, list2)))
>>> list1
(1, 1, 2, 3, 4)
>>> list2 
('one', 'one2', 'two', 'three', 'four')

The above is not returning a list, but can be easily fixed:

>>> list1, list2 = (list(t) for t in zip(*sorted(zip(list1, list2))))
>>> list1
[1, 1, 2, 3, 4]
>>> list2
['one', 'one2', 'two', 'three', 'four']

It's worth noting that the above may sacrifice speed for terseness; the in-place version, which takes up 3 lines, is a tad faster on my machine for small lists:

>>> %timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 3.3 us per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best of 3: 2.84 us per loop

On the other hand, for larger lists, the one-line version could be faster:

>>> %timeit zip(*sorted(zip(list1, list2)))
100 loops, best of 3: 8.09 ms per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100 loops, best of 3: 8.51 ms per loop

I think the zip-based approach is more flexible and is a little more readable, so I prefer it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.