内置函数sorted的10个小tips

简介: sorted 用于对集合进行排序(这里说的集合是对可迭代对象的一个统称,他们可以是列表、字典、set、甚至是字符串),它的功能非常强大,本文将深入浅出地介绍 sorted 的各种使用场景。

sorted 用于对集合进行排序(这里说的集合是对可迭代对象的一个统称,他们可以是列表、字典、set、甚至是字符串),它的功能非常强大,本文将深入浅出地介绍 sorted 的各种使用场景。

1、默认排序

1、默认情况,sorted 函数将按列表升序进行排序,并返回一个新列表对象,原列表保持不变,最简单的排序

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

2、降序排序

2、降序排序,如果要按照降序排列,只需指定参数 reverse=True 即可

>>> sorted(nums, reverse=True)
[5, 4, 3, 2, 1]

3、自定义规则排序

3、如果要按照某个特定的规则排序,则需指定参数 key, key 是一个函数(或其它可调用对象),例如:一个字符串构成的列表,我想按照字符串的长度来排序

>>> chars = ['Andrew', 'This', 'a', 'from', 'is', 'string', 'test']
>>> sorted(chars, key=len)
['a', 'is', 'from', 'test', 'This', 'Andrew', 'string']

len 是内建函数,sorted 函数在排序的时候会用len去获取每个字符串的长度来排序。 有些人可能使用匿名函数 key=lambda x: len(x) ,其实是多此一举。

>>> chars = ['Andrew', 'This', 'a', 'from', 'is', 'string', 'test']
>>> sorted(chars, key=lambda x: len(x))
['a', 'is', 'from', 'test', 'This', 'Andrew', 'string']

4、复合排序

4、如果是一个复合列表结构,例如:由元组构成的列表,要按照元组中的第二个元素排序,那么可以用 lambda 定义一个匿名函数,这里就是按照第二个元素的字母升序来排列的

>>> students = [('zhang', 'A'), ('li', 'D'), ('wang', 'C')]
>>> sorted(students, key=lambda x: x[1])
[('zhang', 'A'), ('wang', 'C'), ('li', 'D')]

这里将按照字母 A-C-D 的顺序排列。

5、类的实例对象排序

5、如果要排序的元素是自定义类,例如Student类按照年龄来排序,则可以写成

>>> 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('lily', 'A', 12),
     Student('dave', 'B', 10), ]
>>> sorted(student_objects, key=lambda t:t.age)
[('dave', 'B', 10), ('jane', 'B', 12), ('lily', 'A', 12), ('john', 'A', 15)]

6、多个值排序

6、和数据库的排序一样,sorted 也可以根据多个字段来排序,例如我有先要根据age排序,如果age相同的则根据grade排序,则可以使用元组:

>>> sorted(student_objects, key=lambda t:(t.age, t.grade))
[('dave', 'B', 10), ('lily', 'A', 12), ('jane', 'B', 12), ('john', 'A', 15)]

7. 不可直接比较的值排序

7、前面碰到的排序场景都是建立在两个元素是可以互相比较的前提下,例如数值按大小比较, 字母按ASCII顺序比较,如果遇到本身是不可比较的,需要我们自己来定义比较规则的情况如何处理呢?

举个简单的例子:

>>> nums = [2, 1.5, 2.5, '2', '2.5']
>>> sorted(nums)
TypeError: '<' not supported between instances of 'str' and 'int'

一个整数列表中,可能有数字,字符串,在Python3中,字符串与数值是不能比较的,而Python2中任何类型都可以比较,这是两个版本中一个很大的区别:

# python2.7
>>> "2.5" > 2
True
# python3.6
>>> "2.5" > 2
TypeError: '>' not supported between instances of 'str' and 'int'

我们需要使用 functools 模块中的 cmp_to_key 来指定比较函数是什么。

import functools
def compare(x1, x2):
    if isinstance(x1, str):
        x1 = float(x1)
    if isinstance(x2, str):
        x2 = float(x2)
    return x1 - x2
>>>sorted(nums, key=functools.cmp_to_key(compare))
[1.5, 2, '2', 2.5, '2.5']

8、定义com_to_key

8、关于 sorted 函数,Python2和Python3之间的区别是Python2中的sorted 可以指定cmp关键字参数,就是当遇到需要自定义比较操作的数据可以通过 cmp=compare 来实现,不需要像Python3中还需要导入functools.cmp_to_key实现。

nums = [2, 1.5, 2.5, '2', '2.5']
def compare(x1, x2):
    if isinstance(x1, str):
        x1 = float(x1)
    if isinstance(x2, str):
        x2 = float(x2)
    return 1 if x1 - x2 > 0 else -1 if x1 - x2 < 0 else 0
>>> sorted(nums, cmp=compare)
[1.5, 2, '2', 2.5, '2.5']

其实,在Python2中,上面这种情况你不指定cmp,默认也会按照这种方式排序,记住,Python2中,任何东西(不同类型之间)都可以比较,而Python3只有同类型数据可以比较。

9、优化排序

9、 对于集合构成的列表,有一种更高效的方法指定这个key

>>> from operator import itemgetter
>>> sorted(students, key=itemgetter(1))
[('zhang', 'A'), ('wang', 'C'), ('li', 'D')]

10、高级排序

10、同样的,对于自定义类,也有一种更高效的方法指定key

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

如果参与排序的字段有两个怎么办,你可以这样:

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

以上是关于 sorted 函数的全部。

目录
相关文章
|
JSON 数据格式 Python
Python json中一直搞不清的load、loads、dump、dumps、eval
Python json中一直搞不清的load、loads、dump、dumps、eval
846 0
Python json中一直搞不清的load、loads、dump、dumps、eval
|
Windows
windows 技巧篇-解除共享文件夹占用方法,解决共享文件被占用导致不可修改问题,查看共享文件被谁占用方法
windows 技巧篇-解除共享文件夹占用方法,解决共享文件被占用导致不可修改问题,查看共享文件被谁占用方法
2438 0
windows 技巧篇-解除共享文件夹占用方法,解决共享文件被占用导致不可修改问题,查看共享文件被谁占用方法
|
数据采集 数据处理 索引
DataFrame
【10月更文挑战第13天】
1079 2
|
9月前
|
人工智能 搜索推荐 物联网
线上共学 | Mac本地玩转大模型
本文介绍如何在Mac本地部署和使用大模型,包括基础运行、多模态扩展、交互优化、知识增强、定制进化等技术链路,并提供Ollama、Stable Diffusion、LM-Studio等工具的详细操作指南。
1861 8
|
机器学习/深度学习 索引 Python
技术经验分享:DataFrame(1):结构介绍
技术经验分享:DataFrame(1):结构介绍
693 0
|
数据采集 人工智能 数据可视化
Python selenium爬虫被检测到,该怎么破?
Python selenium爬虫被检测到,该怎么破?
1737 9
|
JSON 前端开发 JavaScript
JSON文件如何读取?
JSON文件如何读取?
875 5
|
存储 关系型数据库 数据库
python中内存错误(MemoryError)
【5月更文挑战第3天】
779 1
|
传感器 人工智能 供应链
【AI 场景】如何应用 AI 来优化供应链管理
【5月更文挑战第3天】【AI 场景】如何应用 AI 来优化供应链管理
【AI 场景】如何应用 AI 来优化供应链管理
|
数据采集 数据可视化 数据挖掘
利用 DataFrame 进行数据分析:实战案例解析
【5月更文挑战第19天】DataFrame是数据分析利器,本文通过一个销售数据案例展示其使用:读取数据创建DataFrame,计算产品总销量,分析月销售趋势,找出最畅销产品,并进行数据可视化。此外,还提及数据清洗和异常处理。DataFrame为数据处理、分组计算和可视化提供便利,助力高效数据分析。
326 3

热门文章

最新文章