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合并多个装饰器小技巧
Apr 28 Python
简单实现python进度条脚本
Dec 18 Python
Python with语句上下文管理器两种实现方法分析
Feb 09 Python
python统计字母、空格、数字等字符个数的实例
Jun 29 Python
使用Python实现租车计费系统的两种方法
Sep 29 Python
python多线程扫描端口(线程池)
Sep 04 Python
Django3.0 异步通信初体验(小结)
Dec 04 Python
Django 自定义404 500等错误页面的实现
Mar 08 Python
python标准库OS模块函数列表与实例全解
Mar 10 Python
Python实现爬取并分析电商评论
Jun 19 Python
python怎么判断素数
Jul 01 Python
python 利用Pyinstaller打包Web项目
Oct 23 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
PHP生成带有雪花背景的验证码
2006/10/09 PHP
利用PHP和AJAX创建RSS聚合器的代码
2007/03/13 PHP
php数据库抽象层 PDO
2011/05/07 PHP
PHP小技巧之JS和CSS优化工具Minify的使用方法
2014/05/19 PHP
Laravel5中防止XSS跨站攻击的方法
2016/10/10 PHP
javascript实现 在光标处插入指定内容
2007/05/25 Javascript
JS支持带x身份证号码验证函数
2008/08/10 Javascript
CSS(js)限制页面显示的文本字符长度
2012/12/27 Javascript
两种方法实现文本框输入内容提示消失
2013/03/17 Javascript
js调试系列 控制台命令行API使用方法
2014/06/18 Javascript
轻松创建nodejs服务器(9):实现非阻塞操作
2014/12/18 NodeJs
BootStrap智能表单实战系列(九)表单图片上传的支持
2016/06/13 Javascript
微信小程序 input表单与redio及下拉列表的使用实例
2017/09/20 Javascript
vue.js使用watch监听路由变化的方法
2018/07/08 Javascript
js微信分享接口调用详解
2019/07/23 Javascript
Webpack按需加载打包chunk命名的方法
2019/09/22 Javascript
[52:03]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第三场 1月31日
2021/03/11 DOTA
python的tkinter布局之简单的聊天窗口实现方法
2014/09/03 Python
python3爬取各类天气信息
2018/02/24 Python
python生成不重复随机数和对list乱序的解决方法
2018/04/09 Python
Python3数据库操作包pymysql的操作方法
2018/07/16 Python
python实现二维插值的三维显示
2018/12/17 Python
pytorch实现线性拟合方式
2020/01/15 Python
python将unicode和str互相转化的实现
2020/05/11 Python
python网络编程之五子棋游戏
2020/05/14 Python
css3 自定义字体font-face使用介绍
2014/05/14 HTML / CSS
巴西最好的男鞋:Rafarillo
2018/05/25 全球购物
项目管理计划书
2014/01/09 职场文书
平民服装店创业计划书
2014/01/17 职场文书
社区包粽子活动方案
2014/01/21 职场文书
学生党支部先进事迹
2014/02/04 职场文书
幼儿园秋游感想
2014/03/12 职场文书
垃圾桶标语
2014/06/24 职场文书
2014年学习厉行节约反对浪费思想汇报
2014/09/10 职场文书
乡镇组织委员个人整改措施
2014/09/16 职场文书
2015团员个人年度总结
2015/11/24 职场文书