用 Python 排序数据的多种方法

用 Python 排序数据的多种方法

目录

【Python HOWTOs系列】排序

Python 列表有内置就地排序的方法 list.sort(),此外还有一个内置的 sorted() 函数将一个可迭代对象(iterable)排序为一个新的有序列表。

本文我们将去探索用 Python 做数据排序的多种方法。

排序基础

简单的升序排序非常容易:只需调用 sorted() 函数,就得到一个有序的新列表:

你也可以使用 list.sort() 方法,此方法为就地排序(并且返回 None 来避免混淆)。通常来说这不如 sorted() 方便——但是当你不需要保留原始列表的时候,这种方式略高效一些。

另外一个区别是 list.sort() 方法只可以供列表使用,而 sorted() 函数可以接受任意可迭代对象(iterable)。

Key 函数

list.sort() 和 sorted() 都有一个 key 参数,用于指定在作比较之前,调用何种函数对列表元素进行处理。 For example, here’s a case-insensitive string comparison: 例如,忽略大小写的字符串比较:

key 参数的值应该是一个函数,该函数接收一个参数,并且返回一个 key 为排序时所用。这种方法速度很快,因为每个输入项仅调用一次 key 函数。

一种常见模式是使用对象的下标作为 key 来排序复杂对象。例如:

同样的技巧也可以用在带有命名属性(named attributes)的对象上。例如:

上述的 key 函数模式是非常常见的,所以 Python 提供了一些更简单快速的访问属性的函数。operator 模块有 itemgetter()、attrgetter() 和 methodcaller() 函数。 Using those functions, the above examples become simpler and faster: 使用这些函数,可以使上述的示例更加简洁高效:

operator 模块方法允许多级排序。例如,可以先按 grade 排序,然后再按 age 排序:

list.sort() 和 sorted() 都有布尔型的 reverse 参数,用来指定是否降序。例如,按 age 的降序来对学生数据进行排序:

排序是保证为稳定的,也就是说,当多条记录拥有相同的 key 时,原始的顺序会被保留下来。

注意到两条 blue 记录保持了原来的顺序, 所以 (‘blue’, 1) 一定在 (‘blue’, 2) 之前。

这个非常棒的属性允许你通过一系列排序来进行复杂排序。例如,学生数据先按 grade 升序,然后按 age 降序,优先排序 age,然后再按 grade 排序:

Python 使用的 Timsort 算法由于可以有效利用数据集中已有的顺序,因而可以高效地进行多级排序。

使用 Decorate-Sort-Undecorate 的旧方法

Decorate-Sort-Undecorate 的名称来源于这种方法的三个步骤:

  • 第一步,初始的列表进行转换,获得用于排序的新值。
  • 第二步,将转换为新值的列表进行排序。
  • 最后,还原数据并得到一个排序后仅包含原始值的列表。

例如,使用 DSU(译注:Decorate-Sort-Undecorate的简写)方法,按 grade 来排序学生数据:

>>> decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]

>>> decorated.sort()

>>> [student for grade, i, student in decorated] # undecorate

[(‘john’, ‘A’, 15), (‘jane’, ‘B’, 12), (‘dave’, ‘B’, 10)]

这一方法利用了元组按字典序 (lexicographically) 比较的特性;先比较第一项;如果第一项相同,则比较第二项,以此类推。

在很多情况下是不需要在处理后的列表(decorated list)包含原始下标 i,但是包含原始下标有两个好处:

排序是稳定的——如果有两项有相同的 key,排序后的列表会保留他们的顺序。

原始项不需要是可比较的,因为处理后的元组最多使用前面两项就可以决定排序。例如,原始列表中包含无法直接比较的复数。

这个方法还有另外一个名字,是以 Randal L. Schwartz 的名字来命名的 Schwartzian 变换,因为他使得这个变换在 Perl 程序员中得以流行。

在 Python 排序提供 key 函数之后,这个技巧已经不常用了。

使用 cmp 参数的旧方法

本篇指南中给出的方法都假设 Python 2.4 或更新版本。在 2.4 之前,sorted() 和 list.sort() 是没有 key 参数的。但是,在所有的 Py2.x 版本都支持 cmp 参数来处理用户自定义排序函数。

在 Py3.0 中,cmp 参数已经被完全移除(作为简化和统一语言的一部分,去除排序和 cmp() 魔法方法之间的冲突)。

在 Py2.x 中,sort 允许传入一个可选函数,会在进行比较的时候调用。函数必须接受两个参数进行比较,然后返回负数表示小于,返回 0 表示相等,返回正数表示大于。例如,我们可以这样:

或者你也可以反转比较顺序:

当从 Python 2.x 移植代码到 3.x 时,可能会出现需要将用户提供的排序函数转换为 key 函数的情况。下面的包装器可以轻松做到:

转换为 key 函数,仅需要包装旧的比较函数即可:

在 Python 3.2 中,functools.cmp_to_key() 函数已经添加到标准库的 functools 模块中。

其他要点

针对时区相关排序,使用 locale.strxfrm() 作为 key 函数,或者使用 locale.strcoll() 作为比较函数。

reverse 参数仍然保持排序稳定性(以便相同 key 的项保留原顺序)。有趣的是,无需传入参数,通过两次调用内置的 reversed() 函数,可以模拟出相同的效果:

在两个对象进行比较时,sort 使用的是 lt() 方法。所以,只需要为类添加 lt() 方法,就可以为类加入排序顺序:

key 函数不需要直接依赖于排序的对象。key 函数可以访问外部资源。例如,如果学生的成绩保存在字典中,字典中的数据可以给单独的一个学生名字排序:

英文出处:Andrew Dalke,Raymond Hettinger

文章来源36大数据,www.36dsj.com ,微信号dashuju36 ,36大数据是一个专注大数据创业、大数据技术与分析、大数据商业与应用的网站。分享大数据的干货教程和大数据应用案例,提供大数据分析工具和资料下载,解决大数据产业链上的创业、技术、分析、商业、应用等问题,为大数据产业链上的公司和数据行业从业人员提供支持与服务。

时间: 2024-10-19 14:24:54

用 Python 排序数据的多种方法的相关文章

通过Rest service获取后台数据的多种方法

开发在开发网页的时候用Rest service来获取Json数据,然后对数据进行组织后显示在网页上,那我们在做自动化测试的时候对这种情况需要验证的有以下2点: 1. Service的数据可以正常被获取到 2. 数据都正确的被网页显示出来并且显示在正确的地方 那么要做这2点验证,自动化测试的具体步骤如下 1. 通过方法获取到这个service中的数据(json,xml) 2.通过解析json或xml来对数据进行整理和提取 3. 验证这些整理过的数据都显示在正确的地方 后面2点再说,对于第一点获取的

Delphi导出数据的多种方法

//Dxdbgrid,则直接用SaveToexcel即可//使用 ExcelWithOdbc 控件function TDataModule1.GetDataToFile(DsData: TObject): Boolean; //用于将数据导入文件中var   DataSet: TCustomADODataSet;   FileName: string;   FileType: string;begin   if not ((DsData is TCustomADODataSet) or (DsD

Python学习——数据排序方法

Python对数据排序又两种方法: 1. 原地排序:采用sort()方法,按照指定的顺序排列数据后用排序后的数据替换原来的数据(原来的顺序丢失),如: >>> data1=[4,2,6,432,78,43,22,896,42,677,12] >>> data1.sort() >>> data1 #原来的顺序被替换 [2, 4, 6, 12, 22, 42, 43, 78, 432, 677, 896] 2. 复制排序:采用sorted()内置函数,按照

python list排序的两种方法及实例讲解

对List进行排序,Python提供了两个方法 方法1.用List的内建函数list.sort进行排序 list.sort(func=None, key=None, reverse=False) Python实例: >>> list = [2,5,8,9,3] >>> list [2,5,8,9,3] >>> list.sort() >>> list [2, 3, 5, 8, 9] 方法2.用序列类型函数sorted(list)进行排

使用Python解析JSON数据的基本方法

这篇文章主要介绍了使用Python解析JSON数据的基本方法,是Python入门学习中的基础知识,需要的朋友可以参考下: ----------------------------------------------------------------- Python的json模块提供了一种很简单的方式来编码和解码JSON数据. 其中两个主要的函数是 json.dumps() 和 json.loads() , 要比其他序列化函数库如pickle的接口少得多. 下面演示如何将一个Python数据结构

Python使用plotly绘制数据图表的方法

转载:http://www.jb51.net/article/118936.htm 本篇文章主要介绍了Python使用plotly绘制数据图表的方法,实例分析了plotly绘制的技巧. 导语:使用 python-plotly 模块来进行压测数据的绘制,并且生成静态 html 页面结果展示. 不少小伙伴在开发过程中都有对模块进行压测的经历,压测结束后大家往往喜欢使用Excel处理压测数据并绘制数据可视化视图,但这样不能很方便的使用web页面进行数据展示.本文将介绍使用python-plotly模块

列表[‘hello’ , ‘python’ ,’!’ ] 用多种方法拼接,并输出’hello python !’ 以及join()在python中的用法简介

列表['hello' , 'python' ,'!' ] 用多种方法拼接,并输出'hello python !' 使用字符串链接的四种方法都可以创建 字符串拼接一共有四种方法,也可以应用到列表的拼接中 a = ['hello','python','!'] 第一种是用类似字符串相加的方法 #a[0] + ' ' + a[1] + ' ' + a[2] 第二种是用%s 连接起来 #'%s %s %s'%(a[0],a[1],a[2]) 第三种是用 join 连接起来 '''这里先普及join()在p

queryList 一次抓取多个网页内容的方法--目前只有用循环 替换页码或者给出url循环进行 queryList没有像python一样的yied迭代方法 queryList 实现多个实例抓取不同网页的内容,两个实例数据互不干扰

注意: 目前只有用循环 替换页码或者给出url循环进行   queryList没有像python一样的yied迭代方法  queryList 实现多个实例抓取不同网页的内容,两个实例数据互不干扰 新技能获取: Medoo(轻量级php数据库框架:https://medoo.lvtao.net/) 实现循环采集多个页面数据: 关键代码  for ($i = 1; $i < 21; $i++) { echo "正在爬取第{$i}页\n"; $url = "http://bl

Python进行数据可视化的9种常见方法,总有一种是你要用的

其实利用 Python 可视化数据并不是很麻烦,因为 Python 中有两个专用于可视化的库 matplotlib 和 seaborn 能让我们很容易的完成任务. 我们用 Python 可以做出哪些可视化图形? 当你给别人一个表格比如: 这个表给别人看起来,既不舒服,也不好观看.最最最最最最重要的一点就是low! 在学习过程中有什么不懂得可以加我的 python学习交流扣扣qun,784758214 群里有不错的学习视频教程.开发工具与电子书籍. 与你分享python企业当下人才需求及怎么从零基