Sorting list based on values from another list?

后端 未结 15 2304
温柔的废话
温柔的废话 2020-11-21 07:14

I have a list of strings like this:

X = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\"]
Y = [ 0,   1,   1,   0,   1,   2,   2,   0,   1 ]
         


        
15条回答
  •  有刺的猬
    2020-11-21 08:06

    This is an old question but some of the answers I see posted don't actually work because zip is not scriptable. Other answers didn't bother to import operator and provide more info about this module and its benefits here.

    There are at least two good idioms for this problem. Starting with the example input you provided:

    X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
    Y = [ 0,   1,   1,   0,   1,   2,   2,   0,   1 ]
    

    Using the "Decorate-Sort-Undecorate" idiom

    This is also known as the Schwartzian_transform after R. Schwartz who popularized this pattern in Perl in the 90s:

    # Zip (decorate), sort and unzip (undecorate).
    # Converting to list to script the output and extract X
    list(zip(*(sorted(zip(Y,X)))))[1]                                                                                                                       
    # Results in: ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')
    

    Note that in this case Y and X are sorted and compared lexicographically. That is, the first items (from Y) are compared; and if they are the same then the second items (from X) are compared, and so on. This can create unstable outputs unless you include the original list indices for the lexicographic ordering to keep duplicates in their original order.

    Using the operator module

    This gives you more direct control over how to sort the input, so you can get sorting stability by simply stating the specific key to sort by. See more examples here.

    import operator    
    
    # Sort by Y (1) and extract X [0]
    list(zip(*sorted(zip(X,Y), key=operator.itemgetter(1))))[0]                                                                                                 
    # Results in: ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')
    

提交回复
热议问题