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中为什么要用self探讨
Apr 14 Python
Python中的rjust()方法使用详解
May 19 Python
python版本的读写锁操作方法
Apr 25 Python
浅析python中SQLAlchemy排序的一个坑
Feb 24 Python
Java分治归并排序算法实例详解
Dec 12 Python
对python中的for循环和range内置函数详解
Apr 17 Python
使用Python创建简单的HTTP服务器的方法步骤
Apr 26 Python
Python redis操作实例分析【连接、管道、发布和订阅等】
May 16 Python
Python使用os.listdir和os.walk获取文件路径
May 21 Python
通过Django Admin+HttpRunner1.5.6实现简易接口测试平台
Nov 11 Python
浅析Python中的随机采样和概率分布
Dec 06 Python
Django框架中视图的用法
Jun 10 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
层叠菜单的动态生成
2006/10/09 PHP
PHP中如何判断AJAX提交的数据
2012/02/05 PHP
PHP中的使用curl发送请求(GET请求和POST请求)
2017/02/08 PHP
用javascript动态调整iframe高度的代码
2007/04/10 Javascript
怎么选择Javascript框架(Javascript Framework)
2013/11/22 Javascript
js锁屏解屏通过对$.ajax进行封装实现
2014/07/31 Javascript
简介JavaScript中的push()方法的使用
2015/06/09 Javascript
jQuery实现带有上下控制按钮的简单多行滚屏效果代码
2015/09/04 Javascript
Javascript中判断一个值是否为undefined的方法详解
2016/09/28 Javascript
解决浏览器会自动填充密码的问题
2017/04/28 Javascript
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
2017/11/10 jQuery
element UI upload组件上传附件格式限制方法
2018/09/04 Javascript
小程序指纹验证的实现代码
2018/12/04 Javascript
JavaScript数据结构与算法之检索算法实例分析【顺序查找、最大最小值、自组织查询】
2019/02/22 Javascript
JavaScript监听键盘事件代码实现
2020/06/03 Javascript
详解pandas.DataFrame中删除包涵特定字符串所在的行
2019/04/04 Python
django框架实现模板中获取request 的各种信息示例
2019/07/01 Python
python画图——实现在图上标注上具体数值的方法
2019/07/08 Python
python 使用cx-freeze打包程序的实现
2020/03/14 Python
python数据库编程 ODBC方式实现通讯录
2020/03/27 Python
使用Python防止SQL注入攻击的实现示例
2020/05/21 Python
CSS3与动画有关的属性transition、animation、transform对比(史上最全版)
2017/08/18 HTML / CSS
html5 video全屏播放/自动播放的实现示例
2020/08/06 HTML / CSS
天猫超市:阿里巴巴打造的网上超市
2016/11/02 全球购物
美国运动鞋类和服装零售连锁店:Shoe Palace
2019/08/13 全球购物
公务员职务工作的自我评价
2013/11/01 职场文书
门卫岗位职责说明书
2014/08/18 职场文书
银行会计主管岗位职责
2014/10/01 职场文书
四川省传达学习贯彻党的群众路线教育实践活动总结大会精神新闻稿
2014/10/26 职场文书
2014年旅游局法制宣传日活动总结
2014/11/01 职场文书
2015年“7.11”世界人口日宣传活动方案
2015/05/06 职场文书
军训后的感想
2015/08/07 职场文书
运动会广播稿50字
2015/08/19 职场文书
python基于机器学习预测股票交易信号
2021/05/25 Python
Python中OpenCV实现查找轮廓的实例
2021/06/08 Python
MySQL性能指标TPS+QPS+IOPS压测
2022/08/05 MySQL