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 21 Python
在Python中测试访问同一数据的竞争条件的方法
Apr 23 Python
Python面向对象编程之继承与多态详解
Jan 16 Python
Pycharm无法使用已经安装Selenium的解决方法
Oct 13 Python
代码详解django中数据库设置
Jan 28 Python
python for循环remove同一个list过程解析
Aug 14 Python
浅谈python中统计计数的几种方法和Counter详解
Nov 07 Python
Python统计时间内的并发数代码实例
Dec 28 Python
Python paramiko 模块浅谈与SSH主要功能模拟解析
Feb 29 Python
Django如何使用redis作为缓存
May 21 Python
Python命名空间及作用域原理实例解析
Aug 12 Python
据Python爬虫不靠谱预测可知今年双十一销售额将超过6000亿元
Nov 11 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实现长连接的方法与注意事项的问题
2013/05/10 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(七)
2014/06/23 PHP
PHP简单获取网站百度搜索和搜狗搜索收录量的方法
2016/08/23 PHP
php版微信开发之接收消息,自动判断及回复相应消息的方法
2016/09/23 PHP
thinkPHP订单数字提醒功能的实现方法
2016/12/01 PHP
JavaScript DOM学习第八章 表单错误提示
2010/02/19 Javascript
jQuery插件实现表格隔行换色且感应鼠标高亮行变色
2013/09/22 Javascript
获取鼠标在div中的相对位置的实现代码
2013/12/30 Javascript
jQuery的图片滑块焦点图插件整理推荐
2014/12/07 Javascript
JavaScript调用传递变量参数的相关问题及解决办法
2015/11/01 Javascript
AngularJS基础 ng-list 指令详解及示例代码
2016/08/02 Javascript
js实现浏览器倒计时跳转页面效果
2016/08/12 Javascript
JS+Canvas绘制动态时钟效果
2017/11/10 Javascript
laravel5.3 vue 实现收藏夹功能实例详解
2018/01/21 Javascript
vue源码解析之事件机制原理
2018/04/21 Javascript
JavaScript中filter的用法实例分析
2019/02/27 Javascript
让python同时兼容python2和python3的8个技巧分享
2014/07/11 Python
Python中请使用isinstance()判断变量类型
2014/08/25 Python
Python计算一个文件里字数的方法
2015/06/15 Python
基于Python pip用国内镜像下载的方法
2018/06/12 Python
详解python:time模块用法
2019/03/25 Python
Django中celery执行任务结果的保存方法
2019/07/12 Python
python递归法解决棋盘分割问题
2019/07/17 Python
Django ORM filter() 的运用详解
2020/05/14 Python
解决pyinstaller打包运行程序时出现缺少plotly库问题
2020/06/02 Python
keras 两种训练模型方式详解fit和fit_generator(节省内存)
2020/07/03 Python
Python3爬虫中关于Ajax分析方法的总结
2020/07/10 Python
一套SQL笔试题
2016/08/14 面试题
校园奶茶店创业计划书
2014/01/23 职场文书
幼儿园大班毕业感言
2014/02/06 职场文书
2014年教师个人工作总结
2014/11/10 职场文书
2014年基建工作总结
2014/12/12 职场文书
2014年小学数学工作总结
2014/12/12 职场文书
2015新教师教学工作总结
2015/07/22 职场文书
2016年“12.4”法制宣传日活动总结
2016/04/01 职场文书
解决pytorch读取自制数据集出现过的问题
2021/05/31 Python