• python排序


    python中的list有个内建的排序方法 list.sort() 但是这个排序方法会修改原list。python中还有一个内置的排序函数 sorted() ,他是根据给定的iterable返回一个新的排过序的list。

    下面的文档,我们会给你展示python中排序的各种技术。

    基本排序

    简单的升续是很容易实现的:只需要调用 sorted() 内建函数。就可以返回一个新的排过序的list:

    >>> sorted([5, 2, 3, 1, 4])
    [1, 2, 3, 4, 5]

    你也可以使用list对象的 list.sort() 方法来进行排序。但是他会修改原list。通常我们排序会优先考虑 sorted() 内建函数,但是如果你不再需要原list,其实也是很方便的。

    >>> a = [5, 2, 3, 1, 4]
    >>> a.sort()
    >>> a
    [1, 2, 3, 4, 5]

    还有一点, list.sort() 方法只有list中定义了。相反 sorted() 可以对所有可迭代的对象进行排序。

    >>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
    [1, 2, 3, 4, 5]

    Key 函数

    从python2.4开始,在 list.sort() 和 sorted() 中,都增加了一个参数:key,key参数是一个函数,python会在排序之前,调用key函数对每个排序的元素进行处理,之后对key返回的处理后元素进行排序。

    例如:对字符串进行大小写不敏感的排序:

    >>> sorted("This is a test string from Andrew".split(), key=str.lower)
    ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

     key参数必须是个带有一个参数的函数,他的返回值是用来排序的。由于每个排序元素只调用一次key函数,它的存在并不会影响排序的速度。

    一个常用的用法是:在对复杂对象排序时,使用复杂对象的下标来作为key函数。例如:

    >>> student_tuples = [
    ...     ('john', 'A', 15),
    ...     ('jane', 'B', 12),
    ...     ('dave', 'B', 10),
    ... ]
    >>> sorted(student_tuples, key=lambda student: student[2])   # sort by age
    [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

    同样的方法也可以使用到对象的属性上。例如:

    >>> class Student:
    ...     def __init__(self, name, grade, age):
    ...         self.name = name
    ...         self.grade = grade
    ...         self.age = age
    ...     def __repr__(self):
    ...         return repr((self.name, self.grade, self.age))
    >>> student_objects = [
    ...     Student('john', 'A', 15),
    ...     Student('jane', 'B', 12),
    ...     Student('dave', 'B', 10),
    ... ]
    >>> sorted(student_objects, key=lambda student: student.age)   # sort by age
    [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

    Operator模块的函数

    对于大部分排序来说,key函数是通用的,所以python提供了很多简单易用的函数。operator模块中就有 operator.itemgetter() , operator.attrgetter() 等函数;在python2.5后,又加入了 operator.methodcaller() 函数。

    如果使用python提供的这些函数,上面的几个例子就会变得更简单:

    >>> from operator import itemgetter, attrgetter
    >>> sorted(student_tuples, key=itemgetter(2))
    [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
    >>> sorted(student_objects, key=attrgetter('age'))
    [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

    operator模块的函数,也支持多维度的排序。例如,现根据grade排序,再根据age排序:

    >>> sorted(student_tuples, key=itemgetter(1,2))
    [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
    >>> sorted(student_objects, key=attrgetter('grade', 'age'))
    [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

     operator.methodcaller() 函数更牛逼,他可以指定一个被排序的元素的某个方法,还可以给该方法指定一个固定的参数。例如,可以使用 str.count() 方法来计算每个排序元素中感叹号的个数,并以此作为排序的优先级:

    >>> from operator import methodcaller
    >>> messages = ['critical!!!', 'hurry!', 'standby', 'immediate!!']
    >>> sorted(messages, key=methodcaller('count', '!'))
    ['standby', 'hurry!', 'immediate!!', 'critical!!!']

    升序&降序

    在 list.sort() 和  sorted() 中还有一个reverse的boolean参数,用来指定排序的顺序。例如,根据学生数据中年龄的降序排序:   

    >>> sorted(student_tuples, key=itemgetter(2), reverse=True)
    [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
    >>> sorted(student_objects, key=attrgetter('age'), reverse=True)
    [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

    排序的稳定性和复杂排序

    从python2.2开始,python中的排序都是稳定的。排序是稳定的是指:如果有多个元素有相同的优先级,排序后,拥有相同优先级的元素的相对位置不变。

    >>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
    >>> sorted(data, key=itemgetter(0))
    [('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]

    注意,元素 ('blue', 1) 和元素 ('blue', 2) 的相对顺序和原来一样。

    更妙的是,我们可以分多步来完成一个更复杂的排序。例如:在student数据中,我们先根据grade降序排,再根据age的升序排。

    >>> s = sorted(student_objects, key=attrgetter('age'))     # sort on secondary key
    >>> sorted(s, key=attrgetter('grade'), reverse=True)       # now sort on primary key, descending
    [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

    多重排序请使用python为我们提供的Timsort算法。

    参考:

    https://docs.python.org/2/howto/sorting.html#sortinghowto

  • 相关阅读:
    SpringMvc 的小dome
    解决Eclipse加载Tomcat报错Could not load the Tomcat server configuration.The configuration may be corrupt or incomplete.
    【转载】理解java三层架构:持久层、业务层、表现层
    Eclipse 报错 org.springframework.context.support.AbstractApplicationContext refresh处理
    Eclipes 报错The ... package is not accessible解决
    Tomcat文件目录及用途
    MyBatis配置文件mybatis-config.xml中的mappers中引入映射文件的几种方式总结
    Mybatis中自动生成主键在mysql和Oracle当中的情况
    mybatis中int类型的判断问题分析
    Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 56; columnNumber: 17
  • 原文地址:https://www.cnblogs.com/halu126/p/6679831.html
Copyright © 2020-2023  润新知