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的Tornado框架实现数据可视化的教程
May 02 Python
Python selenium文件上传方法汇总
Nov 19 Python
Python使用smtp和pop简单收发邮件完整实例
Jan 09 Python
Python使用装饰器模拟用户登陆验证功能示例
Aug 24 Python
使用11行Python代码盗取了室友的U盘内容
Oct 23 Python
python读取csv和txt数据转换成向量的实例
Feb 12 Python
Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
Jun 25 Python
python查找重复图片并删除(图片去重)
Jul 16 Python
Python3 使用selenium插件爬取苏宁商家联系电话
Dec 23 Python
Python3实现英文字母转换哥特式字体实例代码
Sep 01 Python
python实现测试工具(一)——命令行发送get请求
Oct 19 Python
python 利用百度API识别图片文字(多线程版)
Dec 14 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下载excel无法打开的解决方法
2013/12/24 PHP
PHP中的访问修饰符简单比较
2019/02/02 PHP
javascript编程起步(第七课)
2007/02/27 Javascript
Jquery index()方法 获取相应元素索引值
2012/10/12 Javascript
jquery创建一个ajax关键词数据搜索实现思路
2013/02/26 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
2013/08/14 Javascript
jQuery设置与获取HTML,文本和值的简单实例
2014/02/26 Javascript
基于jQuery实现的图片切换焦点图整理
2014/12/07 Javascript
js实现简单鼠标跟随效果的方法
2015/04/10 Javascript
avalonjs制作响应式瀑布流特效
2015/05/06 Javascript
jQuery解析XML文件同时动态增加js文件的方法
2015/06/01 Javascript
JavaScript中对象的不同创建方法
2016/08/12 Javascript
微信小程序 图片宽高自适应详解
2017/05/11 Javascript
jQuery实现的简单对话框拖动功能示例
2018/06/05 jQuery
vuex 动态注册方法 registerModule的实现
2019/07/03 Javascript
JavaScript交换变量常用4种方法解析
2020/09/02 Javascript
JS删除对象中某一属性案例详解
2020/09/08 Javascript
Python检测QQ在线状态的方法
2015/05/09 Python
Python实现比较两个文件夹中代码变化的方法
2015/07/10 Python
Django中模版的子目录与include标签的使用方法
2015/07/16 Python
Python读写Json涉及到中文的处理方法
2016/09/12 Python
Python heapq使用详解及实例代码
2017/01/25 Python
python实现协同过滤推荐算法完整代码示例
2017/12/15 Python
Python实现根据日期获取当天凌晨时间戳的方法示例
2019/04/09 Python
python 已知平行四边形三个点,求第四个点的案例
2020/04/12 Python
Python暴力破解Mysql数据的示例
2020/11/09 Python
CSS3实现DIV圆角效果完整代码
2012/10/10 HTML / CSS
新百伦折扣店:Joe’s New Balance Outlet
2016/08/20 全球购物
环法自行车赛官方商店:Le Tour de France
2017/08/27 全球购物
伊芙丽官方旗舰店:中国淑女一线品牌
2017/12/01 全球购物
联想法国官方网站:Lenovo法国
2018/10/18 全球购物
JDK安装目录下有哪些内容
2014/08/25 面试题
幼儿园门卫制度
2014/01/29 职场文书
银行青年文明号事迹材料
2014/05/31 职场文书
爱情保证书
2015/01/17 职场文书
租赁协议书
2015/01/27 职场文书