challenge ?

Discussion in 'Python' started by alain, Mar 22, 2007.

  1. alain

    alain Guest

    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
     
    alain, Mar 22, 2007
    #1
    1. Advertising

  2. Hi,

    On 22 Mar 2007 09:41:43 -0700
    "alain" <> wrote:

    > 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-----
     
    Frank Benkstein, Mar 22, 2007
    #2
    1. Advertising

  3. On Mar 22, 9:41 am, "alain" <> wrote:
    > 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)}
     
    Raymond Hettinger, Mar 22, 2007
    #3
  4. Hi, again,

    On Thu, 22 Mar 2007 18:11:46 +0100
    Frank Benkstein <> wrote:

    > On 22 Mar 2007 09:41:43 -0700
    > "alain" <> wrote:
    >
    > > 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.


    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-----
     
    Frank Benkstein, Mar 22, 2007
    #4
  5. alain

    Paul Rubin Guest

    "alain" <> writes:
    > 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)
     
    Paul Rubin, Mar 22, 2007
    #5
  6. alain wrote:
    > 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
    >
    >>> d = dict(a=10, b=5, c=8, d=12)


    >>> dict((k, (v, rank)) for rank, (v, k) in

    ... 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
     
    Michael Spencer, Mar 22, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Artco News

    Parsing challenge...

    Artco News, Oct 7, 2003, in forum: Perl
    Replies:
    6
    Views:
    479
    Ara.T.Howard
    Oct 8, 2003
  2. Artco News

    Parsing challenge...

    Artco News, Oct 7, 2003, in forum: Perl
    Replies:
    2
    Views:
    425
    Ed Morton
    Oct 7, 2003
  3. .Net Newbie
    Replies:
    0
    Views:
    470
    .Net Newbie
    Jul 29, 2004
  4. Random

    XML challenge!

    Random, Nov 16, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    2,293
    Marshal Antony
    Nov 16, 2004
  5. Raj Thakkar
    Replies:
    8
    Views:
    562
    Patrick Olurotimi Ige
    Dec 9, 2004
Loading...

Share This Page