How can I get 2.x-like sorting behaviour in Python 3.x?

后端 未结 10 880
陌清茗
陌清茗 2020-11-27 06:50

I\'m trying to replicate (and if possible improve on) Python 2.x\'s sorting behaviour in 3.x, so that mutually orderable types like int, float etc.

10条回答
  •  甜味超标
    2020-11-27 07:19

    One way for Python 3.2+ is to use functools.cmp_to_key(). With this you can quickly implement a solution that tries to compare the values and then falls back on comparing the string representation of the types. You can also avoid an error being raised when comparing unordered types and leave the order as in the original case:

    from functools import cmp_to_key
    
    def cmp(a,b):
        try:
            return (a > b) - (a < b)
        except TypeError:
            s1, s2 = type(a).__name__, type(b).__name__
            return (s1 > s2) - (s1 < s2)
    

    Examples (input lists taken from Martijn Pieters's answer):

    sorted([0, 'one', 2.3, 'four', -5], key=cmp_to_key(cmp))
    # [-5, 0, 2.3, 'four', 'one']
    sorted([0, 123.4, 5, -6, 7.89], key=cmp_to_key(cmp))
    # [-6, 0, 5, 7.89, 123.4]
    sorted([{1:2}, {3:4}], key=cmp_to_key(cmp))
    # [{1: 2}, {3: 4}]
    sorted([{1:2}, None, {3:4}], key=cmp_to_key(cmp))
    # [None, {1: 2}, {3: 4}]
    

    This has the disadvantage that the three-way compare is always conducted, increasing the time complexity. However, the solution is low overhead, short, clean and I think cmp_to_key() was developed for this kind of Python 2 emulation use case.

提交回复
热议问题