# sorting two corresponding lists?

Discussion in 'Python' started by Esmail, Apr 20, 2009.

1. ### EsmailGuest

Hello all,

I wonder if someone could help me with sorting two corresponding lists.

For instance the first list contains some items, and the second list
contains their value (higher is better)

items = [apple, car, town, phone]
values = [5, 2, 7, 1]

I would like to sort the 'items' list based on the 'values' list so
that I end up with the following two list:

items = [town, apple, car, phone]
values = [7, 5, 2, 1]

So I would like to keep the corresponding value still corresponding
after the sorting.

Is there an easy/nice/Pythonic way to do this?

Thanks,
Esmail

Esmail, Apr 20, 2009

2. ### Diez B. RoggischGuest

items = zip(*sorted(zip(values, items)))[1]

To better understand this please note that

a = [1, 2]
b = [3, 4]

zip(*zip(a, b)) == a, b

or, in other words, zip(*argument) is the inverse of an argument created by
zip (under the assumption the a and b have equal length)

Diez

Diez B. Roggisch, Apr 20, 2009

3. ### SakethGuest

Why not use a dictionary instead of two lists? Then you can sort the
dictionary by value -- e.g.

d = dict(zip(items, values))
sorted_items = sorted(d.iteritems(), key=lambda (k,v): (v,k))

This produces a list of pairs, but demonstrates the general idea.

Saketh, Apr 20, 2009
4. ### EsmailGuest

Hi Diez,

Thanks for this, I had seen zip() before but had no idea
really what it does, this will serve as good motivation to
find out more.

I'm amazed at what this language can do (and the helpfulness
of the people on the list here).

Best,
Esmail

Esmail, Apr 20, 2009
5. ### EsmailGuest

Hi Diez,

Thanks for this, I had seen zip() before but had no idea
really what it does, this will serve as good motivation to
find out more.

I'm amazed at what this language can do (and the helpfulness
of the people on the list here).

Best,
Esmail

Esmail, Apr 20, 2009
6. ### EsmailGuest

thanks for the suggestion. I am not sure this is quite suitable for my
application (the example I provided was extremely simplified), but this
is a useful technique to know and has been stored away for future use.

Thanks again,
Esmail

Esmail, Apr 20, 2009
7. ### EsmailGuest

thanks for the suggestion. I am not sure this is quite suitable for my
application (the example I provided was extremely simplified), but this
is a useful technique to know and has been stored away for future use.

Thanks again,
Esmail

Esmail, Apr 20, 2009
8. ### Arnaud DelobelleGuest

One way I have not seen in any reply is to sort the indices first.
Create a list of all indices:
[0, 1, 2, 3]

Sort the indices according to the value at each index:

[2, 0, 1, 3]

Now you can get the sorted values and items without further sorting:

['town', 'apple', 'car', 'phone']

This can be spelt:
HTH

Arnaud Delobelle, Apr 20, 2009
9. ### Peter OttenGuest

An exotic option:
[7, 5, 2, 1]

Peter

Peter Otten, Apr 21, 2009
10. ### Piet van OostrumGuest

This will fail if there are duplicates in the items. And if we assume no
duplicates the key doesn't need the k part:

sorted_items = sorted(d.iteritems(), key=lambda (k,v): v)

or

from operator import itemgetter
sorted_items = sorted(d.iteritems(), key=itemgetter(1))

Piet van Oostrum, Apr 23, 2009
11. ### EsmailGuest

Cool .. always good to know alternative ways of accomplishing

Esmail

Esmail, Apr 23, 2009
12. ### EsmailGuest

Cool .. always good to know alternative ways of accomplishing

Esmail

Esmail, Apr 23, 2009
13. ### Hans DushanthaKumarGuest

Just being pedantic here

[items[x] for x in [i for i in map(values.index, new_values)]]

Is the same as

[items[x] for x in map(values.index, new_values)]

-----Original Message-----
From: python-list-bounces+hans.dushanthakumar=
[mailtoython-list-bounces+hans.dushanthakumar=]
On Behalf Of Esmail
Sent: Friday, 24 April 2009 3:02 AM
To: tiefeng wu
Cc:
Subject: Re: sorting two corresponding lists?

Cool .. always good to know alternative ways of accomplishing

Esmail

Hans DushanthaKumar, Apr 24, 2009
14. ### Arnaud DelobelleGuest

It's also the same as

[items[x] for x in [values.index(i) for i in new_values]]

Which reduces to

[items[values.index(i)] for i in new_values]

(Although 'i' is not a good choice of variable as it represents a
value, not an index)

Anyway it doesn't work well if the 'values' list has repeated values,
e.g.

items = ['spam', 'eggs', 'wafer']
values = [3, 7, 3]

Arnaud Delobelle, Apr 24, 2009