Python3:复杂数据结构的排序

排序是非常常见的一个场景,相比于Python2,Python3中的排序有不少优化,今天谈一谈Python3中常见排序场景~~更多细节可参考Ref中的Python官方文档链接(虽然里面也没有多少内容,不过很权威啊)

1. 基本排序

基本排序,有两种方式:sorted(list)和list.sort,前者sorted为一个函数,返回一个sorted的新list,后者为list的一个内建方法,在原list的基础上进行排序

2. 使用关键字key='...'

问题:想按照每个元素第三个值进行从小到大的排序,数据结构如下

student_tuples = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10) ]

方法:

sorted(student_tuples, key=lambda item: item[2])

解析:sorted函数执行时,遍历student_tuples中的每个元素,这里通过取出每个元素的第三个元素作为返回值用于排序,这里lambda函数的功能相当于:

def func(item):

return item[2]

对于简单些的数据结构,可以使用lambda函数,如若遇到更复杂情形,则建议自定义函数,使用自定义函数方式如下:

sorted(student_tuples, key=func)

*注意,自定义函数传给sorted函数key关键字时,无需为自定义函数提供参数,sorted函数遍历元素时,自动将参数传递给函数,用于判断排序

3.一个复杂排序规则的实现

问题:一个字符串排序,排序规则:小写

实现:

sorted(s, key=lambda x: (x.isdigit(),x.isdigit() and int(x) % 2 == 0,x.isupper(),x)

解析:

(1).x.isdigit()的作用是把数字放在后边(True),字母放在前面(False).

(2).x.isdigit() and int(x) % 2 == 0的作用是保证数字中奇数在前(False),偶数在后(True)。

(3).x.isupper()的作用是在前面基础上,保证字母小写(False)在前大写在后(True).

(4). 最后的x表示在前面基础上,对所有类别数字或字母排序。

(5). False=0,True=1,因此当一个元素被判断为False时,将会按照由小到大排在前面,同时元组内(e1, e2, e3)的优先级排列为: e1 > e2 > e3,如同excel中的主排序和次排序类似

4. 简化功能,使用operator模块

两个数据结构示例:

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_tuples = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10) ]

排序方案:

from operator import itemgetter, attrgetter

sorted(student_objects, key=attrgetter('age'))

sorted(student_tuples, key=itemgetter(2))

针对上述两个数据结构的排序将会更快速(未测试,参考官方文档),同时由于operator是python内建模块,用起来应该还是比lambda匿名函数或自定义函数方便一些些的~

重要的事情再强调一下,当为key关键字提供一个元组时,会按照元组内的元素顺序进行优先级顺序排序,参见下例:

sorted(student_tuples, key=itemgetter(1,2))

output: [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

5. 升序,降序

这一块比较简单,只需为reverse关键字提供True或False即可,不提供时则默认为False(升序)

参考资料:

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

本文来自企鹅号 - 全球大搜罗媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

3117 高精度乘法

3117 高精度练习之乘法  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解 题目描述 Description 给出...

35412
来自专栏十月梦想

对象的属性方法调用的两种方法

782
来自专栏Ryan Miao

java中String的相等比较

首先贴出测试用例: ? 1 package test; 2 3 import org.junit.Test; 4 5 /** 6 * Crea...

2866
来自专栏开源优测

[快学Python3]String(字符串)

概述 字符串是Python中最常用的数据类型,通常我们使用引号(单引' 或 双引" 或 三引号""")来创建字符串。 在python3中,所有的字符串都是Uni...

3127
来自专栏吾爱乐享

JAVA之学习system类的概述和成员方法

982
来自专栏开发与安全

从零开始学C++之从C到C++(二):引用、数组引用与指针引用、内联函数inline、四种类型转换运算符

一、引用 (1)、引用是给一个变量起别名 定义引用的一般格式:类型  &引用名 = 变量名; 例如:int a=1;  int  &b=a;// b是a的别...

1910
来自专栏Deep learning进阶路

Python随记(一)列表和元组

Python随记(一)列表和元组 Python中最基本的数据结构就是序列了。Python一共包含6种内建序列:列表、元组、字符串、Unicode字符串、xra...

2000
来自专栏九彩拼盘的叨叨叨

学习前端 第5周 第2天

472
来自专栏用户2442861的专栏

java+内存分配及变量存储位置的区别

Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细...

1111
来自专栏浪淘沙

实训day03--循环,内存,数组

2018.06.06 1.switch用法 Scanner sc = new Scanner(System.in); while(t...

1283

扫码关注云+社区

领取腾讯云代金券