Python——内置函数sorted()

1、sorted(iterable[, key][, reverse])

从Iterable中的项返回新的排序列表。
有两个指定关键字的可选参数:[, key]、[, reverse]。

key指定一个参数的函数,该函数用于从每个列表元素中提取比较key:key=str.lower。默认值为None(直接比较元素)。

reverse是一个布尔值。如果设置为True,则列表元素将进行排序,就好像每个比较都颠倒了一样。

2、用法
Python列表有一个内置的list.sort()方法,可以直接修改列表。还有一个sorted()内置函数,它从一个iterable构建一个新的排序列表。

2.1 简单的升序排序
只需调用sorted()函数。它返回一个新的排序列表:

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

还可以使用list.sort()方法。它直接修改列表(并返回NONE以避免混淆)。通常它不如sorted()方便,但是如果您不需要原始列表,它的效率会稍微高一些。

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

另一个不同之处在于list.sort()方法仅为列表定义。相反,sorted()函数接受任何iterable对象。

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

2.2 Key 功能
list.sort()和sorted()都有一个key参数,用于指定在进行比较之前要在每个列表元素上调用的函数。
例如,下面是不区分大小写的字符串比较:
按每个元素首字母的顺序排列,小写字符排在大写字母前。

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

一种常见的模式是使用对象的一些索引作为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)]

2.3 Operator模块功能
上面显示的key-function模式非常常见,因此Python提供了方便的函数来使访问器函数更容易、更快。操作符模块有itemgetter()、attrgetter()和method caller()函数。

from operator import itemgetter, attrgetter
student_tuples = [\
     ('john', 'A', 15),\
     ('jane', 'B', 12),\
     ('dave', 'B', 10),\
 ]
 >>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
from operator import itemgetter, attrgetter
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=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Operator模块函数允许多级排序。例如,要按年级然后按年龄排序,请执行以下操作:

from operator import itemgetter, attrgetter
student_tuples = [\
     ('john', 'A', 15),\
     ('jane', 'B', 12),\
     ('dave', 'B', 10),\
 ]
>>> sorted(student_tuples, key=itemgetter(1,2))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
from operator import itemgetter, attrgetter
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=attrgetter('grade', 'age'))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

2.4 升序和降序
list.sorted()和sorted()都接受带有布尔值的reverse 参数。这用于标记降序排序。例如,要以相反的年龄顺序获取学生数据,请执行以下操作:

from operator import itemgetter, attrgetter
student_tuples = [\
     ('john', 'A', 15),\
     ('jane', 'B', 12),\
     ('dave', 'B', 10),\
 ]
 >>> sorted(student_tuples, key=itemgetter(2), reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
from operator import itemgetter, attrgetter
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=attrgetter('age'), reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

2.5 排序稳定性与复杂排序
保证排序是稳定的。这意味着当多个记录具有相同的key时,它们的原始顺序将被保留。
例如:

from operator import itemgetter
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)前面,所以排序后列表(‘blue’,1)还在(‘blue’,2)前面。
这个奇妙的属性允许您在一系列排序步骤中构建复杂的排序。例如,要先按grade降序再按age升序对学生数据进行排序,请先执行age排序,然后使用grade再次排序:

from operator import itemgetter, attrgetter
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),\
 ]
 >>> 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算法高效地执行多个排序,因为它可以利用数据集中已有的任何排序。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值