Python sorting key function supporting tuples and lists

后端 未结 4 628
你的背包
你的背包 2021-01-22 08:09

In Python you can for example sort tuples sorted([(2,2),(1,2),(2,1),(1,1)]) and get [(1, 1), (1, 2), (2, 1), (2, 2)].

You can also use custom k

相关标签:
4条回答
  • 2021-01-22 08:29
    from collections import Iterable
    def custom_key(item):
        if isinstance(item, Iterable) and not isinstance(item, basestring):
            return [medals_map.get(ele, ele) for ele in item]
        return medals_map.get(item, item)
    

    Output:

    In [2]: assert sorted(['Silver', 'Bronze', 'Gold'], key=custom_key) == ['Gold', 'Silver', 'Bronze']
    
    In [3]: assert sorted([['Silver', 2], ['Silver', 1], ['Gold', 1]], key=custom_key) == [['Gold', 1], ['Silver', 1], ['Silver', 2]]
    
    In [4]: assert sorted([(2, 'Gold'), (2, 'Bronze'), (1, 'Gold')], key=custom_key) == [(1, 'Gold'), (2, 'Gold'), (2, 'Bronze')]
    
    In [5]: assert sorted([('Silver', 'Bronze'), ('Gold', 'Bronze'), ('Silver', 'Gold')], key=custom_key) == [('Gold', 'Bronze'), ('Silver', 'Gold'), ('Silver', 'Bronze')]
    
    0 讨论(0)
  • 2021-01-22 08:30

    You don't need a extra function. You can also do it:

    medals_map = {'Gold': 1, 'Silver': 2, 'Bronze': 3 }
    List = [('Bronze', 1), ('Gold', 1), ('Gold', 2)]
    
    new_list = sorted(List, key=lambda word: (medals_map[word[0]], word[1]))
    
    print new_list
    

    Output:

    [('Gold', 1), ('Gold', 2), ('Bronze', 1)]
    
    0 讨论(0)
  • 2021-01-22 08:33

    The key function can return a tuple:

    medals_map = {'Gold': 1, 'Silver': 2, 'Bronze': 3 }
    
    def custom_key(item):
        if isinstance(item, basestring):
           try:
               return medals_map[item]
           except KeyError:
               pass
        return item
    
    print sorted([('Gold', 2), ('Bronze', 1), ('Gold', 1)], key=lambda x: (custom_key(x[0]), x[1]))
    

    Prints [('Gold', 1), ('Gold', 2), ('Bronze', 1)]. Essentially this makes the sorting behave the same as your first example, i.e. sorted([(1, 2), (3, 1), (1, 1)]).

    Edit: you can also make a custom key that returns a tuple, which may be prettier.

    0 讨论(0)
  • 2021-01-22 08:35

    You could create a mapper function, that takes your key function and returns another function, applying the key function to each element of some iterable.

    def mapper(function):
        def inner(values):
            return tuple([function(x) for x in values])
        return inner
    

    Example:

    >>>sorted([('Gold', 2), ('Bronze', 1), ('Gold', 1)], key=mapper(custom_key))
    [('Gold', 1), ('Gold', 2), ('Bronze', 1)]
    

    Or similar, using functools.partial with map:

    >>> sorted([('Gold', 2), ('Bronze', 1), ('Gold', 1)], key=functools.partial(map, custom_key))
    [('Gold', 1), ('Gold', 2), ('Bronze', 1)]
    
    0 讨论(0)
提交回复
热议问题