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

  2. Esmail wrote:

    > 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
    Diez B. Roggisch, Apr 20, 2009
    #2
    1. Advertising

  3. Esmail

    Saketh Guest

    On Apr 20, 12:10 pm, Esmail <> wrote:
    > 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.
    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

    Diez B. Roggisch wrote:

    > 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
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    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

    Diez B. Roggisch wrote:

    > 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
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    Esmail, Apr 20, 2009
    #5
  6. Esmail

    Esmail Guest

    Saketh wrote:
    >
    >
    > 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
    Esmail, Apr 20, 2009
    #6
  7. Esmail

    Esmail Guest

    Saketh wrote:
    >
    >
    > 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
    Esmail, Apr 20, 2009
    #7
  8. Esmail <> writes:

    > 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:

    >>> indices = range(len(values))
    >>> 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

    --
    Arnaud
    Arnaud Delobelle, Apr 20, 2009
    #8
  9. Esmail

    Peter Otten Guest

    Esmail wrote:

    > 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
    Peter Otten, Apr 21, 2009
    #9
  10. >>>>> Saketh <> (S) wrote:

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

    --
    Piet van Oostrum <>
    URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
    Private email:
    Piet van Oostrum, Apr 23, 2009
    #10
  11. Esmail

    Esmail Guest


    > 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
    Esmail, Apr 23, 2009
    #11
  12. Esmail

    Esmail Guest


    > 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
    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?


    > 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
    --
    http://mail.python.org/mailman/listinfo/python-list
    Hans DushanthaKumar, Apr 24, 2009
    #13
  14. On Apr 24, 2:32 am, "Hans DushanthaKumar"
    <> wrote:
    > 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]

    --
    Arnaud
    Arnaud Delobelle, Apr 24, 2009
    #14
    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. JustSomeGuy

    Sorting lists of lists...

    JustSomeGuy, Jun 17, 2004, in forum: C++
    Replies:
    0
    Views:
    307
    JustSomeGuy
    Jun 17, 2004
  2. David Méndez
    Replies:
    9
    Views:
    491
    Dave Vandervies
    Nov 16, 2004
  3. =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==

    List of lists of lists of lists...

    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==, May 8, 2006, in forum: Python
    Replies:
    5
    Views:
    390
    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==
    May 15, 2006
  4. David Méndez
    Replies:
    10
    Views:
    564
    Dave Vandervies
    Nov 16, 2004
  5. Chris Weisiger

    Help with sorting lists of lists

    Chris Weisiger, Oct 14, 2004, in forum: Perl Misc
    Replies:
    7
    Views:
    121
    Tad McClellan
    Oct 14, 2004
Loading...

Share This Page