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中break语句的用法
May 14 Python
详解字典树Trie结构及其Python代码实现
Jun 03 Python
Python遍历文件夹和读写文件的实现代码
Aug 28 Python
windows下安装python的C扩展编译环境(解决Unable to find vcvarsall.bat)
Feb 21 Python
Python多进程池 multiprocessing Pool用法示例
Sep 07 Python
Python清空文件并替换内容的实例
Oct 22 Python
Python使用Shelve保存对象方法总结
Jan 28 Python
python实现QQ批量登录功能
Jun 19 Python
python的pytest框架之命令行参数详解(上)
Jun 27 Python
解决python中0x80072ee2错误的方法
Jul 19 Python
pycharm-professional-2020.1下载与激活的教程
Sep 21 Python
python爬虫beautifulsoup解析html方法
Dec 07 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语法(1)
2006/10/09 PHP
ThinkPHP3.1新特性之对页面压缩输出的支持
2014/06/19 PHP
PHP实现文件上传与下载实例与总结
2016/03/13 PHP
学习PHP session的传递方式
2016/06/15 PHP
thinkphp中U方法按路由规则生成url的方法
2018/03/12 PHP
区分JS中的undefined,null,&quot;&quot;,0和false
2007/03/08 Javascript
jquery设置text的值示例(设置文本框 DIV 表单值)
2014/01/06 Javascript
node.js中的fs.rmdir方法使用说明
2014/12/16 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
2015/03/13 Javascript
ArtEditor富文本编辑器增加表单提交功能
2016/04/18 Javascript
全面了解构造函数继承关键apply call
2016/07/26 Javascript
AngularJS封装指令方法详解
2016/12/12 Javascript
Angular路由简单学习
2016/12/26 Javascript
微信小程序开发之Tabbar实例详解
2017/01/09 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
2017/01/21 Javascript
xmlplus组件设计系列之网格(DataGrid)(10)
2017/05/05 Javascript
JS之if语句对接事件动作逻辑(详解)
2017/06/28 Javascript
AngularJS基于MVC的复杂操作实例讲解
2017/12/31 Javascript
jquery 通过ajax请求获取后台数据显示在表格上的方法
2018/08/08 jQuery
详解jquery和vue对比
2019/04/16 jQuery
JavaScript实现移动小精灵的案例代码
2020/12/12 Javascript
使用node-media-server搭建一个简易的流媒体服务器
2021/01/20 Javascript
举例详解Python中循环语句的嵌套使用
2015/05/14 Python
Python中用于返回绝对值的abs()方法
2015/05/14 Python
Python神奇的内置函数locals的实例讲解
2019/02/22 Python
python爬取Ajax动态加载网页过程解析
2019/09/05 Python
python中setuptools的作用是什么
2020/06/19 Python
pytorch 中forward 的用法与解释说明
2021/02/26 Python
幼儿园老师寄语
2014/04/03 职场文书
企业安全标语
2014/06/07 职场文书
初三英语教学计划
2015/01/23 职场文书
爱护环境卫生倡议书
2015/04/29 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书
陶瓷类经典广告语集锦
2019/10/25 职场文书
浅谈移动端中的视口(viewport)的具体使用
2021/04/13 HTML / CSS
MySQL创建管理子分区
2022/04/13 MySQL