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实现股市信息下载的方法
Jun 15 Python
利用python发送和接收邮件
Sep 27 Python
Python 3.x读写csv文件中数字的方法示例
Aug 29 Python
python 把列表转化为字符串的方法
Oct 23 Python
python用for循环求和的方法总结
Jul 08 Python
详解Django配置优化方法
Nov 18 Python
python实现实时视频流播放代码实例
Jan 11 Python
深入浅析python 中的self和cls的区别
Jun 20 Python
Python描述数据结构学习之哈夫曼树篇
Sep 07 Python
利用python爬取有道词典的方法
Dec 08 Python
Python中正则表达式对单个字符,多个字符和匹配边界等使用
Jan 27 Python
DjangoRestFramework 使用 simpleJWT 登陆认证完整记录
Jun 22 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
实现在同一方法中获取当前方法中新赋值的session值解决方法
2014/06/26 PHP
php实现模拟登陆方正教务系统抓取课表
2015/05/19 PHP
PHP curl使用实例
2015/07/02 PHP
TP5框架实现自定义分页样式的方法示例
2020/04/05 PHP
用JavaScript实现仿Windows关机效果
2007/03/10 Javascript
基于jquery的固定表头和列头的代码
2012/05/03 Javascript
基于jquery的图片幻灯展示源码
2012/07/15 Javascript
你的 mixin 真的兼容 ECMAScript 5 吗?
2013/04/11 Javascript
js 判断图片是否加载完以及实现图片的预下载
2014/08/14 Javascript
简介JavaScript中POSITIVE_INFINITY值的使用
2015/06/05 Javascript
快速掌握Node.js中setTimeout和setInterval的使用方法
2016/03/21 Javascript
一个字符串中出现次数最多的字符 统计这个次数【实现代码】
2016/04/29 Javascript
JS实现的手机端精简幻灯片效果
2016/09/05 Javascript
javaScript语法总结
2016/11/25 Javascript
Angular 组件之间的交互的示例代码
2018/03/24 Javascript
详解vuex结合localstorage动态监听storage的变化
2018/05/03 Javascript
微信小程序实现上传图片功能
2018/05/28 Javascript
JS实现TITLE悬停长久显示效果完整示例
2020/02/11 Javascript
[51:53]完美世界DOTA2联赛决赛日 Inki vs LBZS 第二场 11.08
2020/11/10 DOTA
[01:01:14]完美世界DOTA2联赛PWL S2 SZ vs Rebirth 第一场 11.21
2020/11/23 DOTA
Python的Flask框架中配置多个子域名的方法讲解
2016/06/07 Python
python用户管理系统
2018/03/13 Python
基于python神经卷积网络的人脸识别
2018/05/24 Python
Django实现学生管理系统
2019/02/26 Python
HTML5中的Scoped属性使用实例
2014/04/23 HTML / CSS
世界第一曲奇连锁店:Mrs. Fields Cookies
2017/02/04 全球购物
德国电子产品购物网站:TechInTheBasket德国
2018/12/07 全球购物
世界上最受欢迎的钓鱼诱饵:Rapala
2019/05/02 全球购物
美国婴儿服装购物网站:Gerber Childrenswear
2020/05/06 全球购物
加拿大大码女装购物网站:Penningtons
2020/12/26 全球购物
《乌鸦和狐狸》教学反思
2014/02/08 职场文书
危爆物品安全大检查大整治工作方案
2014/05/03 职场文书
教师信息技术学习心得体会
2016/01/21 职场文书
初一数学教学反思
2016/02/17 职场文书
巧用 -webkit-box-reflect 倒影实现各类动效(小结)
2021/04/22 HTML / CSS
Django集成富文本编辑器summernote的实现步骤
2021/05/31 Python