python复合条件下的字典排序
作者:天元浪子 发布时间:2022-10-13 20:07:34
知乎上有人说,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]['英语']
))
['白星瑶', '李妍可', '吴诗涵', '庄嘉顺', '邬胜杰']
来源:https://xufive.blog.csdn.net/article/details/108978408


猜你喜欢
- 一个比较好用的字符串截取函数:function substring($str, $start, $length){ //比较好用字符串截取函
- 1、编写TCP服务器程序。2、获取浏览器发送的http请求消息数据。3、读取固定的页面数据,将页面数据组装成HTTP响应消息数据并发送给浏览
- 与ADODB和MDB2相比,PDO更高效。目前而言,实现“数据库抽象层”任重而道远,使用PDO这样的“数据库访问抽象层”是一个不错的选择。
- 基本概述我们知道MySQL有2种方式指定复制同步的方式,分别为:基于binlog文件名及位点的指定方式 - 匿名事
- 错误出现情景在cmd中使用mysql命令,学生信息表添加数据。使用load data方式简单批量导入数据。准备好文本数据: xuesheng
- 问题:MySQL 8.0 无法远程连接访问原因:可能是mysql数据库user表中,用户的 host 字段配置是不允许当前hos
- 使用Django框架搭建后端服务器,后台接收前端传递过来xlsx的文件,直接将前端传递的文件转化为DataFrame或直接将文件保存。url
- Default.aspx<%@ Page Language="C#" AutoEventWireup="
- 前言:存储引擎是数据库的核心,对于 MySQL 来说,存储引擎是以插件的形式运行的。虽然 MySQL 支持种类繁多的存储引擎,但最常用的当属
- 前言在SQL Server数据库中,有时候会建立一些Windows认证的账号(域账号),例如,我们公司习惯给开发人员和Support同事开通
- edt_color_slt.jsvar _r = ""; var color_t
- 我就废话不多说了,大家还是直接看代码吧~#! python3# -*- coding: utf-8 -*-import os, codecs
- 当然可以,我们使用强大的fso对象来获取文件夹的大小请敲入如下代码即可:<%Set MyFileSize =&nb
- (1)查看日期函数拓展phpinfo()<?phpphpinfo();打开上述页面之后,可以看到以下,证明已经安装日期拓展 浏览器输入
- ⭐️ requests的使用(一) 大家好,今天就来说说requests的基础用法。requests是一个很实用的Python H
- CREATE PROCEDURE 创建存储过程,存储过程是保存起来的可以接受和返回用户提供的参数的 Transact-SQL 语句的集合。
- 代码如下:<% function GetBot() '查询蜘蛛 dim s_
- 目的:在numpy数组中知道指定元素的索引函数: np.argwhere>>>x>>>array([[0
- 一、概述本文将介绍如何使用python3给企业微信发送消息。我的环境是linux + python3.6.10。二、python脚本#!/u
- 目前,我们要在网页中使用圆角效果,总是通过切图然后嵌套很多div,用背景来实现圆角效果。对于前端开发工程师来说,圆角的确是一个让人又爱又恨的