Sorting list of lists by a third list of specified non-sorted order

前端 未结 3 1381
我寻月下人不归
我寻月下人不归 2021-01-06 06:18

I have a list:

[[\'18411971\', \'kinase_2\', 36], [\'75910712\', \'unnamed...\', 160], ...
  • about 60 entries long
  • each entry
相关标签:
3条回答
  • 2021-01-06 06:52

    The usual idiom is to sort using a key:

    >>> a = [[1,2],[2,10,10],[3,4,'fred']]
    >>> b = [2,1,3]
    >>> sorted(a,key=lambda x: b.index(x[0]))
    [[2, 10, 10], [1, 2], [3, 4, 'fred']]
    

    This can have performance issues, though-- if the keys are hashable, this will probably be faster for long lists:

    >>> order_dict = dict(zip(b, range(len(b))))
    >>> sorted(a,key=lambda x: order_dict[x[0]])
    [[2, 10, 10], [1, 2], [3, 4, 'fred']]
    
    0 讨论(0)
  • 2021-01-06 06:56

    How about:

    inputlist = [['18411971', 'kinase_2', 36], ['75910712', 'unnamed...', 160], ... # obviously not valid syntax
    auxinput = aux = ['75910712', '18411971', ...] # ditto
    keyed = { sublist[0]:sublist for sublist in inputlist }
    result = [keyed[item] for item in auxinput]
    

    There is no need to use sorting here. For large lists this would be faster, because it's O(n) rather than O(n * log n).

    In case the keys aren't unique, it is possible to use some variant of an ordered dict (e.g. defaultdict(list) as per Niklas B's suggestion) to build the keyed representation.

    0 讨论(0)
  • 2021-01-06 06:56

    So, if I understand you right, you have your sample input list:

    a = [['18411971', 'kinase_2', 36], ['75910712', 'unnamed...', 160], ...
    

    and you want to sort this using an extra list that mentions the order in which the first elements of the sub-lists are to occur in the output:

    aux = ['75910712', '18411971', ...]
    

    If that's right, I think the result can be achieved using something like:

    sorted(a, key = lambda x: aux.index(x[0]))
    
    0 讨论(0)
提交回复
热议问题