sorting two corresponding lists?

E

Esmail

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
 
D

Diez B. Roggisch

Esmail said:
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?

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
 
S

Saketh

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

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.
 
E

Esmail

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
 
E

Esmail

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
 
E

Esmail

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

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
 
E

Esmail

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

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
 
A

Arnaud Delobelle

Esmail said:
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?

One way I have not seen in any reply is to sort the indices first.
values = [5, 2, 7, 1]
items = ['apple', 'car', 'town', 'phone']

Create a list of all indices:
[0, 1, 2, 3]

Sort the indices according to the value at each index:
indices.sort(key=lambda i: values, reverse=True)
indices

[2, 0, 1, 3]

Now you can get the sorted values and items without further sorting:
[values for i in indices] [7, 5, 2, 1]
[items for i in indices]

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

This can be spelt:
map(values.__getitem__, indices) [7, 5, 2, 1]
map(items.__getitem__, indices) ['town', 'apple', 'car', 'phone']

HTH
 
P

Peter Otten

Esmail said:
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]


An exotic option:
values = [5, 2, 7, 1]
items = [apple, car, town, phone]
items.sort(key=lambda item, next=iter(values).next: next(), reverse=True)
values.sort(reverse=True)
items [town, apple, car, phone]
values
[7, 5, 2, 1]

Peter
 
P

Piet van Oostrum

Saketh said:
S> Why not use a dictionary instead of two lists? Then you can sort the
S> dictionary by value -- e.g.
S> d = dict(zip(items, values))
S> sorted_items = sorted(d.iteritems(), key=lambda (k,v): (v,k))
S> This produces a list of pairs, but demonstrates the general idea.

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))
 
E

Esmail

My solution, I know the 'zip' version is more elegant, this is just for
fun:)
items = ['apple', 'car', 'town', 'phone']
values = [5, 2, 7, 1]
new_values = sorted(values, reverse = True)
new_items = [items[x] for x in [i for i in map(values.index, new_values)]]
print(new_values) [7, 5, 2, 1]
print(new_items) ['town', 'apple', 'car', 'phone']

Cool .. always good to know alternative ways of accomplishing
a task.

Esmail
 
E

Esmail

My solution, I know the 'zip' version is more elegant, this is just for
fun:)
items = ['apple', 'car', 'town', 'phone']
values = [5, 2, 7, 1]
new_values = sorted(values, reverse = True)
new_items = [items[x] for x in [i for i in map(values.index, new_values)]]
print(new_values) [7, 5, 2, 1]
print(new_items) ['town', 'apple', 'car', 'phone']

Cool .. always good to know alternative ways of accomplishing
a task.

Esmail
 
H

Hans DushanthaKumar

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: [email protected]
[mailto:p[email protected]]
On Behalf Of Esmail
Sent: Friday, 24 April 2009 3:02 AM
To: tiefeng wu
Cc: (e-mail address removed)
Subject: Re: sorting two corresponding lists?

My solution, I know the 'zip' version is more elegant, this is just for
fun:)
items = ['apple', 'car', 'town', 'phone']
values = [5, 2, 7, 1]
new_values = sorted(values, reverse = True)
new_items = [items[x] for x in [i for i in map(values.index, new_values)]]
print(new_values) [7, 5, 2, 1]
print(new_items) ['town', 'apple', 'car', 'phone']

Cool .. always good to know alternative ways of accomplishing
a task.

Esmail
 
A

Arnaud Delobelle

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)]

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]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,783
Latest member
RickeyDort

Latest Threads

Top