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爬虫抓站的实用技巧
Aug 09 Python
python 获取网页编码方式实现代码
Mar 11 Python
浅谈python爬虫使用Selenium模拟浏览器行为
Feb 23 Python
django自带的server 让外网主机访问方法
May 14 Python
Python爬虫包BeautifulSoup实例(三)
Jun 17 Python
Python使用pickle模块报错EOFError Ran out of input的解决方法
Aug 16 Python
python爬取酷狗音乐排行榜
Feb 20 Python
python+mysql实现教务管理系统
Feb 20 Python
Django的models模型的具体使用
Jul 15 Python
用openCV和Python 实现图片对比,并标识出不同点的方式
Dec 19 Python
Python中sorted()排序与字母大小写的问题
Jan 14 Python
tensorflow 报错unitialized value的解决方法
Feb 06 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
解密ThinkPHP3.1.2版本之独立分组功能应用
2014/06/19 PHP
php-fpm.conf配置文件中文说明详解及重要参数说明
2018/10/10 PHP
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
JavaScript中使用构造器创建对象无需new的情况说明
2012/03/01 Javascript
checkbox使用示例
2013/08/23 Javascript
jquery 实现窗口的最大化不论什么情况
2013/09/03 Javascript
JavaScript如何从listbox里同时删除多个项目
2013/10/12 Javascript
javascript与jquery中跳出循环的区别总结
2013/11/04 Javascript
IE8中使用javascript动态加载CSS的解决方法
2014/06/17 Javascript
node.js中的buffer.slice方法使用说明
2014/12/10 Javascript
jQuery+ajax实现无刷新级联菜单示例
2015/05/21 Javascript
如何制作幻灯片(代码分享)
2017/01/06 Javascript
详解webpack 多页面/入口支持&amp;公共组件单独打包
2017/06/29 Javascript
使用Electron构建React+Webpack桌面应用的方法
2017/12/15 Javascript
解决linux下node.js全局模块找不到的问题
2018/05/15 Javascript
JavaScript创建对象方法实例小结
2018/09/03 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
[44:01]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS paiN
2018/03/31 DOTA
python根据出生年份简单计算生肖的方法
2015/03/27 Python
简单实现Python爬取网络图片
2018/04/01 Python
pygame游戏之旅 如何制作游戏障碍
2018/11/20 Python
python实现移位加密和解密
2019/03/22 Python
使用Python OpenCV为CNN增加图像样本的实现
2019/06/10 Python
python 实现多线程下载视频的代码
2019/11/15 Python
Python代码一键转Jar包及Java调用Python新姿势
2020/03/10 Python
ONLY德国官方在线商店:购买时尚女装
2017/09/21 全球购物
台湾森森购物网:U-mall
2017/10/16 全球购物
有原因的手表:Flex Watches
2019/03/23 全球购物
英国领先的在线鱼贩:The Fish Society
2020/08/12 全球购物
2013的个人自我评价
2013/12/26 职场文书
自强之星事迹材料
2014/05/12 职场文书
党的群众路线教育实践活动领导班子整改措施
2014/09/30 职场文书
店面出租协议书范本
2014/11/28 职场文书
企业党建工作总结2015
2015/05/26 职场文书
争做文明公民倡议书
2019/06/24 职场文书
python使用XPath解析数据爬取起点小说网数据
2021/04/22 Python