sorting two corresponding lists?

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

  1. Esmail

    Esmail Guest

    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
    #1
    1. Advertisements

  2. 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
    #2
    1. Advertisements

  3. Esmail

    Saketh Guest

    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
    #3
  4. Esmail

    Esmail Guest

    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
    #4
  5. Esmail

    Esmail Guest

    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
  6. Esmail

    Esmail Guest

    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
    #6
  7. Esmail

    Esmail Guest

    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
  8. 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
    #8
  9. Esmail

    Peter Otten Guest


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

    Peter
     
    Peter Otten, Apr 21, 2009
    #9
  10. 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
    #10
  11. Esmail

    Esmail Guest

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

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

    Esmail Guest

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

    Esmail
     
    Esmail, Apr 23, 2009
    #12
  13. 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=
    [mailto:python-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
    a task.

    Esmail
     
    Hans DushanthaKumar, Apr 24, 2009
    #13
  14. 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
    #14
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.