Back to Blogs
python
sorting

Sophisticated Sorting

Soloman
2020-06-09

Sophisticated Sorting

1 基础排序

list.sort()会修改list本身且只适用于list,sorted()将返回一个新的list且对所有可迭代序列都有效,默认均按升序排序且为稳定的,可选reverse(True or False)来表示降序或升序排序。

def try_sort():
    a = [2, 5, 3, 1, 8, 7]
    b = sorted(a)
    print(b)
    a.sort(reverse=True)
    print(a)
    
    d = {"x": 3, "h": 6, "f": 4}
    c = sorted(d, reverse=True)
    print(c)
    
    f = [("x", 3), ("h", 6), ("f", 4)]
    g = sorted(f, key=lambda x: x[0])
    print(g)
    h = sorted(f, key=lambda x: x[1])
    print(h)


if __name__ == '__main__':
    try_sort()


[1, 2, 3, 5, 7, 8]
[8, 7, 5, 3, 2, 1]
['x', 'h', 'f']
[('f', 4), ('h', 6), ('x', 3)]
[('x', 3), ('f', 4), ('h', 6)]

2 高级排序

配合使用内置模块 operator

from operator import attrgetter, itemgetter


class Hacker:
    def __init__(self, name, age, gender, language):
        self.name = name
        self.age = age
        self.gender = gender
        self.language = language

    def __repr__(self):
        return repr((
            self.name,
            self.age,
            self.gender,
            self.language
        ))


def try_sort():
    hacker_tuple = [
        ("Ada", 120, 0, "Ada"),
        ("Snake", 30, 2, "Python"),
        ("Cpp", 60, 1, "C++"),
        ("Lsp", 60, 1, "Lisp")
    ]
    hacker_obj = [
        Hacker("Ada", 120, 0, "Ada"),
        Hacker("Snake", 30, 2, "Python"),
        Hacker("Cpp", 60, 1, "C++"),
        Hacker("Lsp", 60, 1, "Lisp")
    ]

    ht1 = sorted(hacker_tuple, key=itemgetter(1))
    ht2 = sorted(hacker_tuple, key=itemgetter(2))
    ht3 = sorted(hacker_tuple, key=itemgetter(3))
    ht4 = sorted(hacker_tuple, key=itemgetter(1, 2, 3))
    sep = "--" * 50
    ho1 = sorted(hacker_obj, key=attrgetter("age"))
    ho2 = sorted(hacker_obj, key=attrgetter("gender"))
    ho3 = sorted(hacker_obj, key=attrgetter("language"))
    ho4 = sorted(hacker_obj, key=attrgetter("age", "gender", "language"))
    for data in [ht1, ht2, ht3, ht4, sep, ho1, ho2, ho3, ho4]:
        print(data)


if __name__ == '__main__':
    try_sort()


[('Snake', 30, 2, 'Python'), ('Cpp', 60, 1, 'C++'), ('Lsp', 60, 1, 'Lisp'), ('Ada', 120, 0, 'Ada')]
[('Ada', 120, 0, 'Ada'), ('Cpp', 60, 1, 'C++'), ('Lsp', 60, 1, 'Lisp'), ('Snake', 30, 2, 'Python')]
[('Ada', 120, 0, 'Ada'), ('Cpp', 60, 1, 'C++'), ('Lsp', 60, 1, 'Lisp'), ('Snake', 30, 2, 'Python')]
[('Snake', 30, 2, 'Python'), ('Cpp', 60, 1, 'C++'), ('Lsp', 60, 1, 'Lisp'), ('Ada', 120, 0, 'Ada')]
----------------------------------------------------------------------------------------------------
[('Snake', 30, 2, 'Python'), ('Cpp', 60, 1, 'C++'), ('Lsp', 60, 1, 'Lisp'), ('Ada', 120, 0, 'Ada')]
[('Ada', 120, 0, 'Ada'), ('Cpp', 60, 1, 'C++'), ('Lsp', 60, 1, 'Lisp'), ('Snake', 30, 2, 'Python')]
[('Ada', 120, 0, 'Ada'), ('Cpp', 60, 1, 'C++'), ('Lsp', 60, 1, 'Lisp'), ('Snake', 30, 2, 'Python')]
[('Snake', 30, 2, 'Python'), ('Cpp', 60, 1, 'C++'), ('Lsp', 60, 1, 'Lisp'), ('Ada', 120, 0, 'Ada')]

构建多个步骤来进行更复杂的排序

# (name, age, gender, language)
def complicated_sort_example():
    hacker_tuple = [
        ("Ada", 120, 0, "Ada"),
        ("Snake", 30, 2, "Python"),
        ("CSharp", 60, 1, "C#"),
        ("Cmm", 60, 1, "C--"),
        ("Lsp", 60, 1, "Lisp")
    ]
    ret1 = sorted(hacker_tuple, key=lambda tp: (tp[1], tp[2]), reverse=True)
    print(ret1)
    ret2 = sorted(ret1, key=lambda tp: tp[0].lower())
    print(ret2)


if __name__ == '__main__':
    complicated_sort_example()
    
    
[('Ada', 120, 0, 'Ada'), ('CSharp', 60, 1, 'C#'), ('Cmm', 60, 1, 'C--'), ('Lsp', 60, 1, 'Lisp'), ('Snake', 30, 2, 'Python')]
[('Ada', 120, 0, 'Ada'), ('Cmm', 60, 1, 'C--'), ('CSharp', 60, 1, 'C#'), ('Lsp', 60, 1, 'Lisp'), ('Snake', 30, 2, 'Python')]