Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort multiple lists simultaneously

Tags:

python

sorting

I have three lists composed of the same number of elements:

a = [0.3, 1.5, 0.2, 2.6]
b = [1, 2, 3, 4]
c = [0.01, 0.02, 0.03, 0.04]

I need to sort these three lists simultaneously according to decreasing values in list a. This means that I have to sort according to a but a also needs to be sorted. The output should look like this:

a_s = [2.6, 1.5, 0.3, 0.2]
b_s = [4, 2, 1, 3]
c_s = [0.04, 0.02, 0.01, 0.03]

This way a_s is now simply sorted by decreasing values while b_s and c_s changed its items positions according to this sorting.

like image 293
Gabriel Avatar asked Nov 12 '13 14:11

Gabriel


1 Answers

Short answer

a_s, b_s, c_s = map(list, zip(*sorted(zip(a, b, c), reverse=True)))

Long answer

First, you have to zip the three lists, creating a single list of items:

>>> a = [0.3, 1.5, 0.2, 2.6]
>>> b = [1, 2, 3, 4]
>>> c = [0.01, 0.02, 0.03, 0.04]
>>> z = zip(a, b, c)
>>> z
[(0.3, 1, 0.01), (1.5, 2, 0.02), (0.2, 3, 0.03), (2.6, 4, 0.04)]

Then, you sort this list. A list of tuples is sorted by their first elements (when first elements are equal, the second one is used, and so on):

>>> zs = sorted(z, reverse=True)
>>> zs
[(2.6, 4, 0.04), (1.5, 2, 0.02), (0.3, 1, 0.01), (0.2, 3, 0.03)]

Then you "unzip" the list. Unzipping is the same as calling zip with each tuple as argument, which is achieved by using the star syntax:

>>> u = zip(*zs)
>>> u
[(2.6, 1.5, 0.3, 0.2), (4, 2, 1, 3), (0.04, 0.02, 0.01, 0.03)]

You get a list of tuples, but you want lists. So, you map the list constructor over these items:

>>> u
[(2.6, 1.5, 0.3, 0.2), (4, 2, 1, 3), (0.04, 0.02, 0.01, 0.03)]
>>> map(list, u)
[[2.6, 1.5, 0.3, 0.2], [4, 2, 1, 3], [0.04, 0.02, 0.01, 0.03]]

You can then unpack the list into variables:

>>> a_s, b_s, c_s = map(list, u)

Observations

When sorting, you can explicitly indicate which item will be used for sorting, instead of relying on tuple's default ordering:

>>> from operator import itemgetter
>>> sorted(z, key=itemgetter(1))  # Sort by second item
[(0.3, 1, 0.01), (1.5, 2, 0.02), (0.2, 3, 0.03), (2.6, 4, 0.04)]
>>> sorted(z, key=itemgetter(2))  # Sort by third item
[(0.3, 1, 0.01), (1.5, 2, 0.02), (0.2, 3, 0.03), (2.6, 4, 0.04)]
like image 143
Roberto Bonvallet Avatar answered Sep 22 '22 06:09

Roberto Bonvallet