python复合条件下的字典排序


Posted in Python onDecember 18, 2020

知乎上有人说,Python3.6以后字典有序且更高效了。群里有同学推荐了这篇文章给我看,并咨询字典排序的问题。

大致浏览了一下,我当即表示不能认同这个说法。这篇文章的作者,应该是一位资深的专业人士,对于Python解释器如何实现字典存储和检索有着深刻地理解。但他犯了一明显的常识性错误:在逻辑上,字典是数据的无序集合,仅依赖于键检索。我们说字典是无序,不是指字典在物理实体上实现的时候真的无序,而是指它的顺序对用户而言没有明确的界定,不能作为数据的特性使用。知乎上这篇文章讲的字典有序,是指字典在物理实体上实现时的有序,而非逻辑上的有序。

既然字典是无序的,为什么还有那么多讨论字典排序的话题呢?其实,在Py2时代,就存在有序字典(orderdict),但有序字典和我们讨论的字典,并非一码事儿。所谓的字典排序,实质上是根据排序规则将字典的键排序,得到的排序结果是一个列表。

我们用一个例子来演示一下字典排序:roster是一个保存学生信息的字典,请按照女生优先、低年级在前、总成绩从高到底排序;如果总成绩相同,则顺序比较语文、数学、英语成绩,高者在前。

roster = {
  '李妍可': {'性别':'女', '年级':3, '语文':98, '数学':95, '英语':100}, 
  '邬胜杰': {'性别':'男', '年级':5, '语文':95, '数学':100, '英语':97},
  '白星瑶': {'性别':'女', '年级':2, '语文':100, '数学':99, '英语':100},
  '吴诗涵': {'性别':'男', '年级':3, '语文':98, '数学':92, '英语':90},
  '庄嘉顺': {'性别':'男', '年级':5, '语文':97, '数学':95, '英语':100}
}

Python最常用的排序函数是sorted(),我们就用sorted()来实现这个排序。如果一次写出复合排序条件,有一定难度。我们化繁为简,一步步实现。

1. 比较总成绩

>>> sorted(roster, key=lambda name:roster[name]['语文']+roster[name]['数学']+roster[name]['英语'])
['吴诗涵', '邬胜杰', '庄嘉顺', '李妍可', '白星瑶']

看起来没有问题,但sorted默认是升序,总成绩从高到底排序的话,要使用reverse=True这个参数。

>>> sorted(roster, key=lambda name:roster[name]['语文']+roster[name]['数学']+roster[name]['英语'], reverse=True)
['白星瑶', '李妍可', '邬胜杰', '庄嘉顺', '吴诗涵']

2. 再来尝试女生优先、低年级在前的两个条件排序

只要在lambda函数中,把排序项并列写出来,sorted()就会自动实现符合条件排序。这里性别排序的条件是'性别'==‘男',对女生而言,结果是False(0),小于男生的True(1),自然就排在了前面。

>>> sorted(roster, key=lambda name:(roster[name]['性别']=='男',roster[name]['年级']))
['白星瑶', '李妍可', '吴诗涵', '邬胜杰', '庄嘉顺']

3. 最终实现

尝试了单个条件和两个条件的排序之后,实现本题目的最终要求就很容易了。不过,成绩降序排列的话,不能直接使用reverse=True,因为会影响性别和年级的排序。我们可以稍微变通一下,达到最终的目的。

>>> sorted(roster, key=lambda name:(
    roster[name]['性别']=='男',
    roster[name]['年级'],
    300-roster[name]['语文']-roster[name]['数学']-roster[name]['英语'],
    100-roster[name]['语文'],
    100-roster[name]['数学'],
    100-roster[name]['英语']
  ))
['白星瑶', '李妍可', '吴诗涵', '庄嘉顺', '邬胜杰']

 到此这篇关于python复合条件下的字典排序的文章就介绍到这了,更多相关python 字典排序内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python 除法小技巧
Sep 06 Python
跟老齐学Python之使用Python操作数据库(1)
Nov 25 Python
Python实现从订阅源下载图片的方法
Mar 11 Python
python使用sorted函数对列表进行排序的方法
Apr 04 Python
PyCharm 常用快捷键和设置方法
Dec 20 Python
python深度优先搜索和广度优先搜索
Feb 07 Python
Python内置函数reversed()用法分析
Mar 20 Python
Python退火算法在高次方程的应用
Jul 26 Python
浅谈Python 列表字典赋值的陷阱
Jan 20 Python
python实现KNN分类算法
Oct 16 Python
python 实现按对象传值
Dec 26 Python
Python3批量创建Crowd用户并分配组
May 20 Python
python 监控服务器是否有人远程登录(详细思路+代码)
Dec 18 #Python
细说NumPy数组的四种乘法的使用
Dec 18 #Python
如何通过python检查文件是否被占用
Dec 18 #Python
python 实现端口扫描工具
Dec 18 #Python
Python-split()函数实例用法讲解
Dec 18 #Python
Python+Opencv实现把图片、视频互转的示例
Dec 17 #Python
python 利用jieba.analyse进行 关键词提取
Dec 17 #Python
You might like
如何提高MYSQL数据库的查询统计速度 select 索引应用
2007/04/11 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
php获取文件大小的方法
2014/02/26 PHP
php中序列化与反序列化详解
2017/02/13 PHP
Laravel模型事件的实现原理详解
2018/03/14 PHP
javascript 获取页面的高度及滚动条的位置的代码
2010/05/06 Javascript
JS打印gridview实现原理及代码
2013/02/05 Javascript
设为首页和收藏的Javascript代码(亲测兼容IE,Firefox,chrome等浏览器)
2013/11/18 Javascript
使用js检测浏览器是否支持html5中的video标签的方法
2014/03/12 Javascript
jquery实现点击页面计算点击次数
2015/01/23 Javascript
第六章之辅组类与响应式工具
2016/04/25 Javascript
Node.js中常规的文件操作总结
2016/10/13 Javascript
js仿新浪微博消息发布功能
2017/02/17 Javascript
详解Vue 动态添加模板的几种方法
2017/04/25 Javascript
js插件实现图片滑动验证码
2020/09/29 Javascript
手机注册发送验证码倒计时的简单实例
2017/11/15 Javascript
如何通过javaScript去除字符串两端的空白字符
2020/02/06 Javascript
Python遍历文件夹和读写文件的实现代码
2016/08/28 Python
python实现多线程抓取知乎用户
2016/12/12 Python
pycharm重置设置,恢复默认设置的方法
2018/10/22 Python
Python3.5运算符操作实例详解
2019/04/25 Python
Python3+PyInstall+Sciter解决报错缺少dll、html等文件问题
2019/07/15 Python
python字典的setdefault的巧妙用法
2019/08/07 Python
python 通过文件夹导入包的操作
2020/06/01 Python
Python3自带工具2to3.py 转换 Python2.x 代码到Python3的操作
2021/03/03 Python
Ted Baker英国官网:男士和女士服装及配件
2017/03/13 全球购物
JACK & JONES荷兰官网:男士服装和鞋子
2021/03/07 全球购物
servlet面试题
2012/08/20 面试题
外贸英语毕业生自荐信
2013/11/14 职场文书
酒店执行总经理岗位职责
2013/12/15 职场文书
电子工程专业毕业生求职信
2014/03/14 职场文书
心理咨询专业自荐信
2014/07/07 职场文书
课外小组活动总结
2014/08/27 职场文书
公安派出所所长四风问题个人对照检查材料
2014/10/04 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
mysql 数据插入优化方法之concurrent_insert
2021/07/01 MySQL