尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python字典赋值还在踩坑?这个默认值技巧让你代码少写一半
数据结构里, 将字典dict予以运用时, 其出现频率是相当之高的, 针对它的运用方法, 有着诸多细微的诀窍。若能把这些诀窍掌握住, 那你运用dict的时候就会效率超高, 并且会让你的代码变得更简洁。1.默认值假设存放的是name和id的映射关系:name_for_userid {1:张三,2:李四,3:王五, }获取中的某一个id的name最简单的方式name_for_userid[1]张三这么一种方式, 虽说简单, 然而存在着一个不太便利的地方, 那便是, 要是去获取一个并不存在于其中的值, 程序便会出现异常。name_for_userid[4]---------------------------------------------------------------------------KeyError Traceback (most recent call last)in()---- 1 name_for_userid[4] KeyError:4多数情形下我们切勿期望程序呈现这般异常为了防止此种状况能够于获取name前先行判定该id是否业已存在于其中。if4inname_for_userid:print(name_for_userid[4])else:print(Not Found)Not Found这种写法虽说具备可行性, 然而其效率欠佳, 之所以如此, 是由于获取某一个id所对应的name最多情况下需要进行两次查询操作: 第一次是先对该id是否存在进行判断, 若存在的话, 那么第二次则从中将name值取出来。另外还存在一种写法:try:print(name_for_userid[4])exceptKeyError:print(Not Found)Not Found在这种写法当中, 代码存在着一定程度的冗余情况, 未能展现出足够的简洁性, 所以呢, dict提供了一种名为get的方法, 该方法具备这样的好处, 那就是能够设置值, 针对那些在dict里并不存在的key, 它会返回某个值, 将此值作为这个key的value。name_for_userid.get(4,None)None2.排序card {a: 4,c: 2,b: 3,d: 1}用对card排序其实是用card的key进行排序如下sorted(card.items())[(a, 4), (b, 3), (c, 2), (d, 1)]有的时候, 我们得针对card的value予以排序, 在这种时候, 便能运用函数里的key这个参数, 我们能对这个函数的用法给予帮助:help(sorted)Help on built-infunction sortedinmodule builtins: sorted(iterable, keyNone, reverseFalse) Return a new list containing all itemsfromthe iterableinascending order.A custom key function can be supplied to customise the sort order,andthe reverse flag can be set to request the resultindescending order.所以我们可以自定义一个key函数:defsorted_by_value(item):returnitem[1] sorted(card.items(),keysorted_by_value)[(d, 1), (c, 2), (b, 3), (a, 4)]其实如果使用匿名函数的话代码会更简洁sorted(card.items(),keylambdaitem:item[1])如果让别人更轻松的理解你的意图你可以尝试用下面的方法importoperator sorted(card.items(),keyoperator.itemgetter(1))要留意的是, .函数所获取的并非值, 反倒定义了一个函数, 借助该函数作用于对象之上以后, 才能够获取该对象上指定域的值。实际上, 相较而言是更为倾向于表达式的, 缘由在于其具备灵活性, 且呈现出简洁的特性, 举例来说, 要是需要依据value的绝对值来对dict进行排序的话, 那么便能够像下面这样去书写:。sorted(card.items(),keylambdaitem:abs(item[1]))3....case据一句流传许久的话语来讲, 往昔、当下以及往后的任何时段之中, 定然不会存在……case语句。之所以会出现这样的状况, 那是由于if…elif…else以及dict均可达成……case语句所具备的功能, 因而……case便丧失了存在下去的必要之处了。ifcond cond_a: handle_a()elifcond cond_b: handle_b()else: handle_default()要是用if...elif...else去达成特定功能, 其优势在于具备较强的可读性, 然而倘若所处理的条件是比较多的那种情况, 如此这般的写法便会显得有一些啰里啰嗦且存在冗余现象。所以呢, 到了这个时候dict就又一次闪亮登场了。func_dict {cond_a: handle_a,cond_b: handle_b } cond cond_a func_dict[cond]()和if...elif...else相比较而言, dict看起来要清爽不少, 除此之外, 要是我们想要达成, 也能够运用dict的get()方法:func_dict.get(cond,handle_default)()这样即使cond不在中程序也不会异常中止。下面再举一个例子如下def dispatch_if(operator, x, y): if operator add: return x y elif operator sub: return x - y elif operator mul: return x * y elif operator div: return x / ydefdispatch_dict(operator, x, y):return{add:lambda: x y,sub:lambda: x -y,mul:lambda: x *y,div:lambda: x /y, }.get(operator,lambda: None)()要是想得更深入些, 从性能方面来讲, 上面所举的例子并非是最优的, 毕竟, 每次在调用函数之际, 都会去生成一个临时的、涵盖各种操作码加减乘除的字典, 而最好的情形无疑是这个字典仅仅生成一回常量, 当下次再度调用这个函数的时候, 直接运用这个字典便行了, 此外, 中的模块已然实现了加减乘除, 比如: .mul、.div , 完全能够替代表达式, 这里仅仅是举个例子, 旨在更妥善地明晰 if…elif…else 和 dict 的异同之处。4.合并dict的几种方法有些时候, 会存在借助一个dict去对另一个dict予以更新的情况, 像是, 利用用户自行定义的配置文件去将默认配置进行覆盖之类的。假定存在下面这样两个dict: xs {a: 1,b: 2} ys {b: 3,c: 4}最常用的就是用dict内置的()方法: zs {}zs.update(xs) zs.update(ys) zs {a: 1, b: 3, c: 4}还有一种方法就是使用内置的dict() zs {**xs, **ys} {a: 1,b: 3,c: 4}5.美观打印在进行打印一些调试信息的操作时, 美观的打印输出, 有时能够让人们很直观地看出关键信息, 进而提高调试的效率。最朴素的打印 mapping {a: 23,b: 42,c: 0xc0ffee}str(mapping){c: 12648430, a: 23, b: 42}借助内置模块json可以实现更加直观的表现形式importjson json.dumps(mapping, indent4, sort_keysTrue) {a: 23,b: 42,c: 12648430}但是这种方法有一定的限制 mapping[d] {1, 2, 3}json.dumps(mapping) TypeError:set([1, 2, 3]) is not JSON serializable json.dumps({all:yup}) TypeError:keys must be a string所以还可以使用下面的方式importpprintpprint.pprint(mapping) {a: 23,b: 42,c: 12648430,d: set([1, 2, 3])}6.彩蛋最后介绍几个关于dict比较有意思的东西 .print(keys:,list({True:yes, 1:no, 1.0:maybe}.keys())) print(values:,list({True:yes, 1:no, 1.0:maybe}.values()))上面的代码会打印出什么结果呢,一开始我认为是下面的输出:keys: [True,1,1.0] values: [yes,no,maybe]真是too young too ,其实结果应是:keys: [True] values: [maybe]缘由何在, 若再度审慎思索, 鉴于键为真, 那么值为何并非肯定而是或许, 进而, 鉴于值为或许, 那键值为何不是一点零却是真, 汝等之疑惑是否与吾相同。其实, 在处理dict表达式之际, 它会先依据dict类去创建出dict的实例, 随后依照item(key:value)于dict表达式里出现的顺序逐个进行赋值, 如下:xs dict() xs[True]yesxs[1] noxs[1.0] maybe更让人觉得奇怪的是, dict会凭借下面的表达式, 判定他的key值全部都是相等的, 是这样的情况, 没错的, 就是这样。True 1 1.0True见到1等于1.0兴许你不会觉得诧异, 然而为何会出现True等于1的情况? 那时看到此处我也存有几分困惑之感。翻阅了一下的官方文档,在这一章节中发现下面这段话:这个类型是那个类型中的一种类型, 并且如同0和1那样, 在所有情况里, 这种情况是当涉及某一事物时, “假”或“真”是被涉及的。标点使用有些杂乱奇怪, 不太能完全理解这段话确切意思, 勉强按要求改写了。意思是讲它属于Int的子类, 而这个子类所包含的就是0与1进而来讲, 我们能够对此进行一番验证。[No,Yes][True]结果果然是Yes,[No,Yes][False]结果也果然是No.但是为了清晰起见,不建议这样用.看到这里你可能会问,这和dict有毛关系.接着往下看:就特定情况而言, True、1以及1.0均指示相同的字典键值, 当解释器于执行字典表达式之际, 它会将后续同一个键True的取值覆盖掉此键True先前的取值, 所以便会出现如下的结果:{True:yes, 1:no, 1.0:maybe} {True:maybe}但是, 为何key没被最后的那个1.0给覆盖掉? 实际上, 道理是蛮简单的, 既然是同样的key, 那为啥还要做额外多余这不必要之事, 耗费多余的时间去更新‘相同的’key? 这是基于解释器性能方面的考量。ys {1.0:no} ys[True]yesys输出:{1.0:yes}依据我们当前所知晓的情况, 从表面状况而言, 是在key值相同之际, 才去覆盖已存在的value值, 然而, 实际情况表明, 这并非仅仅与判定相等有关联, 还有其他因素起作用了, 事实就是如此, 有相关后续影响的。字典借助哈希表得以实现, 这意味着, 它借由将 key 映射至表内一处位置去访问记录, 从而加快查找之速度。此映射函数称作哈希函数, 存放记录的数组名为哈希表。然而并不存在十分完美的哈希函数, 经其计算出的存储位置皆不相同, 故而会出现哈希冲突之情形, 亦即不同的 key 计算出的存储位置为同一地址。接下来瞧瞧究竟是何种因素致使更新 value 值。classAlwaysEquals:def__eq__(self, other):returnTruedef__hash__(self):returnid(self)AlwaysEquals有两个方法:__eq__和__hash__. 首先,由于__eq__返回True,所以下面的条件表达式都是True:AlwaysEquals() AlwaysEquals() AlwaysEquals() 42 AlwaysEquals() waaat?其次,由于返回该对象的id值,也就是内存地址,所以有:objects [AlwaysEquals(),AlwaysEquals(),AlwaysEquals()] [hash(obj)forobjinobjects][140388524604608, 140388524604664, 140388524604720]所以, 综上所述, 在值相同然而哈希值不一样的情况下, 会不会出现值被覆盖的情况呢:{AlwaysEquals():yes, AlwaysEquals():no}结果是:{__main__.AlwaysEquals at 0x7faec023bbe0:yes,__main__.AlwaysEquals at 0x7faec023bac8:no}classSameHash:def__hash__(self):return1aSameHash() b SameHash()由于返回1,所以有: a b Falsehash(a), hash(b) (1, 1)当值不一样可是hash值相同之际, 是不是会有value值被覆盖的情况呢: {a:a, b:b} {:a,:b}综上这两种情况value值都不会被更新。而特定集合{True: yes, 1: no, 1.0: maybe}, 会出现更新键所对应的取值发生变化的情况, 具体原因在于: True 1 1.0True (hash(True), hash(1), hash(1.0)) (1, 1, 1)他们同时满足条件表达式相等且hash值也相等。
RELATED

相关推荐

基于paddlle架构的双摄像头下的行人重识别

基于paddlle架构的双摄像头下的行人重识别

主要使用的是paddle-class和paddle-detection这两个模块; 源代码仓库如下: paddle-class paddle-detection 行人重识别的原理图如下所示: 最后实现的效果,如下所示: vis_c003 vis_c004 所以我们需要先训练,得到我…

📅 2026/9/5 9:52:13
DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning

DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

📅 2026/9/5 19:03:24
GitHub Actions 中 setup-java 步骤详解:JDK 设置与 Maven 依赖缓存

GitHub Actions 中 setup-java 步骤详解:JDK 设置与 Maven 依赖缓存

1. 引言 在 GitHub Actions 工作流中,Java 项目的构建通常需要配置 JDK 环境并管理依赖缓存,以加速构建过程。actions/setup-java 是一个官方 Action,它简化了这些任务。本文将详细解析该步骤如何设置 JDK 并启用 Maven 依赖缓存。 2. acti…

📅 2026/9/12 15:58:16
MORE NEWS

更多资讯

📰

DeFi技术解析:智能合约与金融乐高的工程实践

1. DeFi:当金融遇上区块链乐高第一次接触DeFi是在2020年夏天,当时我在调试一个以太坊智能合约,偶然发现Compound协议允许任何人无需许可地存入加密货币赚取利息。这种完全不同于传统银行的运作方式让我着迷——没有开户审核,没有营…

📰

基于GAN的复杂背景文字修复:从掩码到对抗训练实战

简介:基于生成对抗网络(GAN)实现复杂背景文字图像修复的完整Python源码项目,面向计算机视觉、图像处理方向的开发者与研究者,重点解决自然场景中因遮挡、退化导致的文字模糊或缺失问题。项目利用生成对抗网络对图像进行…

📰

【三个月 AI Agent 实战学习】Day 6:结构化输出(JSON)—— 让模型与代码无缝协作

Day 6 详细展开:结构化输出(JSON)—— 让模型与代码无缝协作 欢迎来到第六天!在前几天,我们学习了如何让模型回答问题、如何让它一步步思考。但在构建 AI Agent 时,模型往往不是最终的执行者——它需要把“…

📰

YOLOv5+ArcFace:从人脸检测到身份识别的完整改进实践

简介:这是一套面向高校计算机、电子信息、数学等专业学生进行课程设计、期末大作业或毕业设计的人脸识别改进方案,基于YOLOv5目标检测框架实现,包含完整源码、测试图片与说明文档。包内共95个文件,压缩后约8.94MB,核心…

📰

Flutter与HarmonyOS 6.0构建旅行记录应用类型选择器

1. 项目背景与核心需求在移动互联网时代,旅行记录类应用已经成为现代人记录生活的重要工具。随着HarmonyOS 6.0的发布和Flutter框架的持续演进,开发者有了更多跨平台开发的选择。本文将详细介绍如何基于Flutter和HarmonyOS 6.0构建一个旅行记录应用中的关…

📰

毕业设计之微信小程序酒店预约管理系统

题目:毕业设计之微信小程序酒店预约管理系统一、项目介绍伴随着全球信息化发展,行行业业都与计算机技术相衔接,计算机技术普遍运用于酒店、宾馆行业。实施计算机系统来管理可以降低酒店成本,使整个酒店的发展和服务水平有显著提升…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬