Python中对元组和列表按条件进行排序的方法示例


Posted in Python onNovember 10, 2015

在python中对一个元组排序

我的同事Axel Hecht 给我展示了一些我所不知道的关于python排序的东西。 在python里你可以对一个元组进行排序。例子是最好的说明:

>>> items = [(1, 'B'), (1, 'A'), (2, 'A'), (0, 'B'), (0, 'a')]
>>> sorted(items)
[(0, 'B'), (0, 'a'), (1, 'A'), (1, 'B'), (2, 'A')]

默认情况下内置的sort和sorted函数接收的参数是元组时,他将会先按元组的第一个元素进行排序再按第二个元素进行排序。 然而,注意到结果中(0, 'B')在(0, 'a')的前面。这是因为大写字母B的ASCII编码比a小。然而,假设你想要一些更人性的排序并且不关注大小写。你或许会这么做:

>>> sorted(items, key=str.lower)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor 'lower' requires a 'str' object but received a 'tuple'

我们将会得到一个错误,因为他不能正确处理元组的第一部分。(注:原文作者估计想说元组中第一项是数字,不能使用lower这个方法;正确的原因提示的很明显了,是因为你传递的是一个元组,而元组是没有lower这个方法的)

我们可以试着写一个lambda函数(eg.sorted(items, key=lambda x: x.lower() if isinstance(x, str) else x)),他将不会工作因为你只处理了元组的一个元素。(注:同上面,作者这么做必然是错的,思考给这个lambda传一个元组,返回的是什么?)

言归正传,下面就是你应该怎么做的方法。一个lambda,它会返回一个元组:

>>> sorted(items, key=lambda x: (x[0], x[1].lower()))
[(0, 'a'), (0, 'B'), (1, 'A'), (1, 'B'), (2, 'A')]

现在你完成了它!谢谢Axel的分享!

我确信你知道你可以倒序排列,仅仅使用sorted(items, reverse=True, …),但是你怎么根据关键字来进行不同的排序?

使用lambda函数返回元组的技巧,下面是一个我们排序一个稍微高级的数据结构:

>>> peeps = [{'name': 'Bill', 'salary': 1000}, {'name': 'Bill', 'salary': 500}, {'name': 'Ted', 'salary': 500}]

现在,使用lambda函数返回一个元组的特性来排序:

>>> sorted(peeps, key=lambda x: (x['name'], x['salary']))
[{'salary': 500, 'name': 'Bill'}, {'salary': 1000, 'name': 'Bill'}, {'salary': 500, 'name': 'Ted'}]

很有意思,对吧?Bill 在Ted的前面,并且500在1000的前面。但是如何在相同的 name 下,对 salary 反向排序?很简单,对它取反:

>>> sorted(peeps, key=lambda x: (x['name'], -x['salary']))
[{'salary': 1000, 'name': 'Bill'}, {'salary': 500, 'name': 'Bill'}, {'salary': 500, 'name': 'Ted'}]

问题:将列表[[1, 2, 3], [4, 5, 6], [7, 8, 9]]排序为[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
分析:

1.转变过程如下:

1 2 3          1 4 7
4 5 6   —> 2 5 8
7 8 9          3 6 9

可以将变换过程看成是原二维数组行(row)变成新数组的列(column),即抽出原数组第一行(row)作为第一列(column),第二行(row)作为第二列(column)…当然也可以将变换过程看成是原数组的列变为新数组的行,限于时间,就暂不考虑这种实现方式。
2.最原始的做法,写两个for循环,外层循环依次迭代数组的行(row),内层循环迭代数组的列(column),来实现这个反转过程,将原数组第一行(row)作为第一列(column),第二行(row)作为第二列(column),过程如下:

In [7]: l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [8]: len_row = 3

In [9]: len_col = 3

In [10]: temp = [[],[],[]]

In [11]: for row in l:
  ....:   for i in range(len_col):
  ....:     temp[i].append(row[i])
  ....:   print temp
  ....:
[[1], [2], [3]]
[[1, 4], [2, 5], [3, 6]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

In [12]:

当然,还可以使用列表推导来做,原理和上面一样,外层迭代row,内层迭代col,生成新的列表:

In [100]: l
Out[100]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [101]: [[row[col] for row in l] for col in range(len(l[0])) ]
Out[101]: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

最后,对这个题目,用zip也可以达到同样的目的:

In [104]: l
Out[104]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [105]: zip(*l)
Out[105]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

In [106]: map(list,zip(*l))
Out[106]: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

*这个符号和列表配合有解压的意思,如l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],则我理解*l就变成了[1, 2, 3], [4, 5, 6], [7, 8, 9]这样三个值,所以zip(*l)和zip([1, 2, 3], [4, 5, 6], [7, 8, 9])的结果才会是一样的,如下:

In [17]: l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [18]: zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
Out[18]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

In [19]: zip(*l)
Out[19]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

In [20]:
Python 相关文章推荐
使用python实现扫描端口示例
Mar 29 Python
Python文件和目录操作详解
Feb 08 Python
人工智能最火编程语言 Python大战Java!
Nov 13 Python
Numpy 将二维图像矩阵转换为一维向量的方法
Jun 05 Python
Django跨域请求问题的解决方法示例
Jun 16 Python
使用Python对微信好友进行数据分析
Jun 27 Python
在Qt中正确的设置窗体的背景图片的几种方法总结
Jun 19 Python
python异常处理、自定义异常、断言原理与用法分析
Mar 23 Python
Python flask框架实现查询数据库并显示数据
Jun 04 Python
keras的ImageDataGenerator和flow()的用法说明
Jul 03 Python
Python爬虫实例之2021猫眼票房字体加密反爬策略(粗略版)
Feb 22 Python
Python Numpy之linspace用法说明
Apr 17 Python
Python 文件管理实例详解
Nov 10 #Python
Python list操作用法总结
Nov 10 #Python
python控制台中实现进度条功能
Nov 10 #Python
使用Python发送各种形式的邮件的方法汇总
Nov 09 #Python
尝试使用Python多线程抓取代理服务器IP地址的示例
Nov 09 #Python
使用Python实现BT种子和磁力链接的相互转换
Nov 09 #Python
Python中MySQLdb和torndb模块对MySQL的断连问题处理
Nov 09 #Python
You might like
PHP中加密解密函数与DES加密解密实例
2014/10/17 PHP
正确的PHP匹配UTF-8中文的正则表达式
2015/05/13 PHP
javascript面向对象的方式实现的弹出层效果代码
2010/01/28 Javascript
jquery $.each() 使用小探
2013/08/23 Javascript
javascript(js)的小数点乘法除法问题详解
2014/03/07 Javascript
ActiveX控件与Javascript之间的交互示例
2014/06/04 Javascript
在JavaScript中构建ArrayList示例代码
2014/09/17 Javascript
对象题目的一个坑 理解Javascript对象
2015/12/22 Javascript
JavaScript快速切换繁体中文和简体中文的方法及网站支持简繁体切换的绝招
2016/03/07 Javascript
对比分析Django的Q查询及AngularJS的Datatables分页插件
2017/02/07 Javascript
vue实现百度搜索下拉提示功能实例
2017/06/14 Javascript
Bootstrap框架建立树形菜单(Tree)的实例代码
2017/10/30 Javascript
nodejs+mongodb aggregate级联查询操作示例
2018/03/17 NodeJs
Vue 2.0双向绑定原理的实现方法
2019/10/23 Javascript
Vuex的各个模块封装的实现
2020/06/05 Javascript
简单介绍Python中的round()方法
2015/05/15 Python
python使用urllib2提交http post请求的方法
2015/05/26 Python
用Python写一个无界面的2048小游戏
2016/05/24 Python
详解Python中contextlib上下文管理模块的用法
2016/06/28 Python
Python实现的人工神经网络算法示例【基于反向传播算法】
2017/11/11 Python
python实现ID3决策树算法
2018/08/29 Python
python判断文件夹内是否存在指定后缀文件的实例
2019/06/10 Python
pyinstaller打包多个py文件和去除cmd黑框的方法
2019/06/21 Python
python logging.info在终端没输出的解决
2020/05/12 Python
Python结合Window计划任务监测邮件的示例代码
2020/08/05 Python
Python利用matplotlib绘制折线图的新手教程
2020/11/05 Python
python给list排序的简单方法
2020/12/10 Python
css3中用animation的steps属性制作帧动画
2019/04/25 HTML / CSS
2019史上最全Database工程师题库
2015/12/06 面试题
什么是Linux虚拟文件系统VFS
2012/01/31 面试题
大学校庆邀请函
2014/01/11 职场文书
酒店优秀员工事迹材料
2014/06/02 职场文书
卖车协议书范本4篇
2014/10/01 职场文书
党的群众路线教育实践活动心得体会(教师)
2014/10/31 职场文书
家长高考寄语
2015/02/27 职场文书
2015年中秋寄语
2015/07/31 职场文书