challenge ?

A

alain

I have a problem I wonder if it has been solved before.
I have a dictionnary and I want the values in the dictionnary to be
annotated with the rank that would be obtained by sorting the values

def annotate_with_rank(my_dict):
....
return my_annotated_dict

In other words, any value a_value would become a 2-tuple
(a_value,rank_of_a_value)

I seek an elegant solution.

Alain
 
F

Frank Benkstein

Hi,

I have a problem I wonder if it has been solved before.
I have a dictionnary and I want the values in the dictionnary to be
annotated with the rank that would be obtained by sorting the values

def annotate_with_rank(my_dict):
....
return my_annotated_dict

In other words, any value a_value would become a 2-tuple
(a_value,rank_of_a_value)

I seek an elegant solution.

In your specification of the problem it is unclear what should be done
with duplicate values. My solution assigns every value a different
rank (starting from 0) such that the highest rank is len(my_dict) - 1.

def annotate_with_rank(my_dict):
items = my_dict.items()
items.sort(key = lambda (k, v): v)
return dict((k, (i, v)) for i, (k, v) in enumerate(items))

Best regards,
Frank Benkstein.


--
GPG (Mail): 7093 7A43 CC40 463A 5564 599B 88F6 D625 BE63 866F
GPG (XMPP): 2243 DBBA F234 7C5A 6D71 3983 9F28 4D03 7110 6D51

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFGArjXiPbWJb5jhm8RAgIaAJ9IQMzxVJtcG1hD9tKQKbdGPZgFTgCfT1VZ
RRLwnt6rrAI7HZ4mBSHRnjY=
=DSNB
-----END PGP SIGNATURE-----
 
R

Raymond Hettinger

I have a problem I wonder if it has been solved before.
I have a dictionnary and I want the values in the dictionnary to be
annotated with the rank that would be obtained by sorting the values

def annotate_with_rank(my_dict):
....
return my_annotated_dict

In other words, any value a_value would become a 2-tuple
(a_value,rank_of_a_value)

Try this:
from operator import itemgetter
my_dict = dict(a=10, b=5, c=8, d=12)
for rank, (key, value) in enumerate(sorted(my_dict.items(), key=itemgetter(1))): .... my_dict[key] = (value, rank)
my_dict
{'a': (10, 2), 'c': (8, 1), 'b': (5, 0), 'd': (12, 3)}
 
F

Frank Benkstein

Hi, again,

In your specification of the problem it is unclear what should be done
with duplicate values. My solution assigns every value a different
rank (starting from 0) such that the highest rank is len(my_dict) - 1.

The two other possibilities were to still make len(my_dict) ranks but
assign equal values an equal rank. That would mean that some ranks are
untaken. Or, lastly, to make only as much ranks as there are unique
values.
def annotate_with_rank(my_dict):
items = my_dict.items()
items.sort(key = lambda (k, v): v)
return dict((k, (i, v)) for i, (k, v) in enumerate(items))

def annotate_with_rank_2(my_dict):
values = my_dict.values()
values.sort()
return dict((k, (values.index(v), v)) for k, v in my_dict.iteritems())

def annotate_with_rank_3(my_dict):
values = list(set(my_dict.itervalues()))
values.sort()
return dict((k, (values.index(v), v)) for k, v in my_dict.iteritems())

Best regards,
Frank Benkstein.

--
GPG (Mail): 7093 7A43 CC40 463A 5564 599B 88F6 D625 BE63 866F
GPG (XMPP): 2243 DBBA F234 7C5A 6D71 3983 9F28 4D03 7110 6D51

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFGArv3iPbWJb5jhm8RAi+DAJ4/5PpmXILgABgeI5Oe8q1oGGguQACfcrMF
zG+u3Cj/IhuFXpDlWjHKZiU=
=tGkI
-----END PGP SIGNATURE-----
 
P

Paul Rubin

alain said:
def annotate_with_rank(my_dict):
....
return my_annotated_dict

In other words, any value a_value would become a 2-tuple
(a_value,rank_of_a_value)

I seek an elegant solution.

Untested:

def annotate_with_rank(my_dict):
s = sorted( ((v,i),k) for i,(k,v) in enumerate(my_dict.iteritems()))
return dict((k,v) for (v,k) in s)
 
M

Michael Spencer

alain said:
I have a problem I wonder if it has been solved before.
I have a dictionnary and I want the values in the dictionnary to be
annotated with the rank that would be obtained by sorting the values

def annotate_with_rank(my_dict):
....
return my_annotated_dict

In other words, any value a_value would become a 2-tuple
(a_value,rank_of_a_value)

I seek an elegant solution.

Alain
... enumerate(sorted((v, k) for k, v in d.items())))
{'a': (10, 2), 'c': (8, 1), 'b': (5, 0), 'd': (12, 3)}
# sort by value, then by key since (v,k) must be unique


Michael
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top