python sort list of tuple

后端 未结 3 687
温柔的废话
温柔的废话 2021-01-22 13:21

I am trying to sorting a list of tuple. for example, If

>>>recommendations = [(\'Gloria Pritchett\', 2), (\'Manny Delgado\', 1), (\'Cameron Tucker\',          


        
相关标签:
3条回答
  • 2021-01-22 13:36

    You can pass in the key to sorted:

    >>> s = sorted(recommendations, key=lambda x: x[1], reverse=True)
    [('Luke Dunphy', 3), ('Gloria Pritchett', 2), ('Manny Delgado', 1), ('Cameron Tucker', 1)]
    

    Then get the names:

    names = [x[0] for x in s]
    # ['Luke Dunphy', 'Gloria Pritchett', 'Manny Delgado', 'Cameron Tucker']
    

    If you've noticed, Manny Delgado and Cameron Tucker are tied based on their key(1), but Manny Delgado comes before Cameron Tucker, because python sorting is in-place. However, based on your desired output, you want the ties in primary key to be resolved using the secondary key (the name in this case). You can do this by first sorting by name and then sorting by the primary integer key:

    t = sorted(recommendations, key=lambda x: x[0])
    s = sorted(t, key=lambda x: x[1], reverse=True)
    # [('Luke Dunphy', 3), ('Gloria Pritchett', 2), ('Cameron Tucker', 1), ('Manny Delgado', 1)]
    

    Note that Cameron Tucker comes before Manny Delgado now. All this and more is covered in detail in the excellent Sorting Howto

    0 讨论(0)
  • 2021-01-22 13:48

    First of all, it sounds like you want to do this:

    Given a list of (name, score) tuples, return a list of names from highest score to lowest score.

    Is that right? I'm going to assume that is the questions.

    Rather than go in to your code (which, when I run it, only returns ONE of the (name, score) pairs, I'll show you how I'd do it.

    First in separate steps:

    recommendations = [
      ('Gloria Pritchett', 2), 
      ('Manny Delgado', 1), 
      ('Cameron Tucker', 1), 
      ('Luke Dunphy', 3)]
    
    rec2 = [(age, name) for name, age in recommendations]
    print rec2
    rec3 = sorted(rec2, reverse=True)
    print rec3
    rec4 = [name for age, name in rec3]
    print rec4
    

    This will print:

    [(2, 'Gloria Pritchett'), (1, 'Manny Delgado'), (1, 'Cameron Tucker'), (3, 'Luke Dunphy')]
    [(3, 'Luke Dunphy'), (2, 'Gloria Pritchett'), (1, 'Manny Delgado'), (1, 'Cameron Tucker')]
    ['Luke Dunphy', 'Gloria Pritchett', 'Manny Delgado', 'Cameron Tucker']
    

    Is that what you are looking for? In my case, "Manny" got sorted before "Cameron" (unlike your intended answer), but if they got the same score, I'm hoping that doesn't matter to you. (If it does, please clarify your question)

    Old timers like me might call this a variant of the Schwartzian transform. (I guess my roots in Perl are showing...)

    Anyway, here's how it works:

    rec2 is a "list comprehension" with score and name swapped.

    rec3 uses the built-in feature of Python to sort tuples, but with reversed=True to get high-to-low sorting.

    rec4 is another "list comprehension" to drop the score and return the name.

    If you must, you may put it all together in a single statement:

    class_rank = [name for age, name in sorted([(age, name) for name, age in recommendations], reverse=True)]
    print class_rank
    

    You are welcome to turn this in to a function, if you'd like.

    Cheers!

    0 讨论(0)
  • 2021-01-22 13:53

    My variation on the sorted theme. I like using itemgetter:

    >>> 
    >>> from operator import itemgetter
    >>> name = itemgetter(0)
    >>> score = itemgetter(1)
    >>> recommendations = [('Gloria Pritchett', 2), ('Manny Delgado', 1), ('Cameron Tucker', 1), ('Luke Dunphy', 3)]
    >>> print '\n'.join(map(name, sorted(recommendations, key = score, reverse = True)))
    Luke Dunphy
    Gloria Pritchett
    Manny Delgado
    Cameron Tucker
    >>> 
    
    0 讨论(0)
提交回复
热议问题