What arguments does Python sort() function have?

前端 未结 3 1859
深忆病人
深忆病人 2020-12-03 01:47

Is there any other argument than key, for example: value?

相关标签:
3条回答
  • 2020-12-03 02:23

    Besides key=, the sort method of lists in Python 2.x could alternatively take a cmp= argument (not a good idea, it's been removed in Python 3); with either or none of these two, you can always pass reverse=True to have the sort go downwards (instead of upwards as is the default, and which you can also request explicitly with reverse=False if you're really keen to do that for some reason). I have no idea what that value argument you're mentioning is supposed to do.

    0 讨论(0)
  • 2020-12-03 02:36

    Yes, it takes other arguments, but no value.

    >>> print list.sort.__doc__
    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
    cmp(x, y) -> -1, 0, 1
    

    What would a value argument even mean?

    0 讨论(0)
  • 2020-12-03 02:44

    Arguments of sort and sorted

    Both sort and sorted have three keyword arguments: cmp, key and reverse.

    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
    cmp(x, y) -> -1, 0, 1
    
    sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list
    

    Using key and reverse is preferred, because they work much faster than an equivalent cmp.

    key should be a function which takes an item and returns a value to compare and sort by. reverse allows to reverse sort order.

    Using key argument

    You can use operator.itemgetter as a key argument to sort by second, third etc. item in a tuple.

    Example

    >>> from operator import itemgetter
    
    >>> a = range(5)
    >>> b = a[::-1]
    >>> c = map(lambda x: chr(((x+3)%5)+97), a)
    >>> sequence = zip(a,b,c)
    
    # sort by first item in a tuple
    >>> sorted(sequence, key = itemgetter(0))
    [(0, 4, 'd'), (1, 3, 'e'), (2, 2, 'a'), (3, 1, 'b'), (4, 0, 'c')]
    
    # sort by second item in a tuple
    >>> sorted(sequence, key = itemgetter(1))
    [(4, 0, 'c'), (3, 1, 'b'), (2, 2, 'a'), (1, 3, 'e'), (0, 4, 'd')]
    
    # sort by third item in a tuple
    >>> sorted(sequence, key = itemgetter(2))
    [(2, 2, 'a'), (3, 1, 'b'), (4, 0, 'c'), (0, 4, 'd'), (1, 3, 'e')]
    

    Explanation

    Sequences can contain any objects, not even comparable, but if we can define a function which produces something we can compare for each of the items, we can pass this function in key argument to sort or sorted.

    itemgetter, in particular, creates such a function that fetches the given item from its operand. An example from its documentation:

    After, f=itemgetter(2), the call f(r) returns r[2].

    Mini-benchmark, key vs cmp

    Just out of curiosity, key and cmp performance compared, smaller is better:

    >>> from timeit import Timer
    >>> Timer(stmt="sorted(xs,key=itemgetter(1))",setup="from operator import itemgetter;xs=range(100);xs=zip(xs,xs);").timeit(300000)
    6.7079150676727295
    >>> Timer(stmt="sorted(xs,key=lambda x:x[1])",setup="xs=range(100);xs=zip(xs,xs);").timeit(300000)
    11.609490871429443
    >>> Timer(stmt="sorted(xs,cmp=lambda a,b: cmp(a[1],b[1]))",setup="xs=range(100);xs=zip(xs,xs);").timeit(300000)
    22.335839986801147
    

    So, sorting with key seems to be at least twice as fast as sorting with cmp. Using itemgetter instead of lambda x: x[1] makes sort even faster.

    0 讨论(0)
提交回复
热议问题