Python 字典键 “三变一” 之谜
开头:读者的“玄学”字典谜题
上周,朋友发来了一段让他抓耳挠腮的代码:
>>> {True: 'foo', 1: 'bar', 1.0: 'baz'}
{True: 'baz'}
“我明明定义了布尔True
、整数1
、浮点数1.0
三个键,结果字典里只剩True
一个键,值还变成了最后一个'baz'
!这是啥情况?”
这条消息让我想起了当年自己初学 Python 时踩过的类似坑 —— 看似 “不同” 的键,在字典里却被 “合并” 了。今天,咱们就用这个新例子当 “线索”,一起拆解 Python 字典的底层逻辑。
第一步:字典的“盖楼”规则
要搞懂三个键为何只剩一个,得先明白字典是怎么“盖楼”的。
简单来说,字典的构建像搭乐高:先拼一个空架子(空字典),再按顺序往架子上装“键值对模块”。上面的代码等价于:
# 1. 拼空架子
my_dict = {}
# 2. 装第一个模块:键是True,值是'foo'
my_dict[True] = 'foo'
# 3. 装第二个模块:键是1,值是'bar'
my_dict[1] = 'bar'
# 4. 装第三个模块:键是1.0,值是'baz'
my_dict[1.0] = 'baz'
重点来了:字典的键是“喜新厌旧”的——如果后装的键和已存在的键“本质相同”,就会覆盖旧值。但问题是:True
(布尔)、1
(整数)、1.0
(浮点数)明明是三种不同的类型,怎么就“本质相同”了?
第二步:True
是“伪装的1”
要破解“键相同”的谜题,得从Python的类型关系说起。
在Python的世界里,布尔(bool
)是整数(int
)的“亲儿子”——官方文档明确写着:
“布尔类型是整数类型的子类型,
True
等价于整数1
,False
等价于整数0
。在大多数上下文中,布尔值的行为与对应的整数值一致。”
这意味着:
True == 1
→ 是真的(True
)1 == 1.0
→ 也是真的(浮点数1.0
的数值等于整数1
)- 所以
True == 1 == 1.0
→ 全等于!
用代码验证:
>>> True == 1
True
>>> 1 == 1.0
True
>>> True == 1 == 1.0
True
原来,在字典的“视角”里,这三个键根本就是“同一个人”!所以当依次插入True: 'foo'
、1: 'bar'
、1.0: 'baz'
时,后两次插入都是在“修改同一个键的值”,最终只保留最后一次的'baz'
。
第三步:哈希值——字典的“身份证号”
但这里还有个疑问:就算三个键“数值相等”,字典怎么确定它们是“同一个键”?难道只看==
吗?
这就要说到字典的底层“黑科技”——哈希表(Hash Table)。字典能快速查找键值对,全靠哈希值:每个键会先通过__hash__
方法生成一个哈希值(类似“身份证号”),字典根据这个号码把键“扔”到对应的“抽屉”里;查找时,也先算哈希值,再去对应的抽屉里找。
关键规则是:只有当两个键的哈希值相同,且==
返回True
时,字典才会认为它们是同一个键。
验证这三个键的哈希值:
>>> hash(True)
1
>>> hash(1)
1
>>> hash(1.0)
1
三个键的哈希值都是1
,==
又全返回True
,字典自然把它们当同一个键。所以后插入的1: 'bar'
和1.0: 'baz'
,本质上都是在修改True
对应的值。
第四步:为什么键是True
而不是1
或1.0
?
最后一个疑问:三个键数值相等、哈希相同,为什么最终字典的键是True
,而不是后插入的1
或1.0
?
这涉及字典的“键保留规则”:当多个键被视为相同时,字典会保留第一个插入的键对象。比如:
>>> temp = {1.0: 'test'}
>>> temp[True] = 'update'
>>> temp
{1.0: 'update'}
这里先插入1.0
,后插入True
(与1.0
相等),字典会保留第一个键1.0
,并更新它的值。回到原问题,原字典第一个插入的键是True
,所以最终键是True
,值被后续插入的'bar'
和'baz'
覆盖。
结论:三个“不同”键的终极真相
现在,我们可以彻底解开这个“变脸字典”的谜题了:
- 类型关系是根源:Python中
bool
是int
的子类,True
等价于1
,1
又等价于1.0
(数值相等)。 - 哈希值是身份证:三个键的哈希值都是
1
,字典通过“哈希值相同+==
为True”判定它们是同一个键。 - 先到先得保键形:字典保留第一个插入的键对象(
True
),后续插入只更新值,不修改键。
所以,最终结果{True: 'baz'}
的本质是:三个键被字典视为同一对象,后插入的值覆盖了前值,而键保留了第一个插入的True
。
写在最后:这行代码教会我的事
这个看似“玄学”的字典表达式,其实藏着Python最核心的设计逻辑:
- 布尔类型的“隐藏身份”(
int
子类) - 字典的哈希表底层逻辑(哈希值+相等性双重校验)
- 键值对的插入顺序对结果的影响
下次遇到类似“反直觉”的代码时,别急着怀疑语言bug——打开Python解释器,用==
和hash()
验证一下,你会发现Python的底层逻辑远比想象中严谨。
毕竟,Python的“奇怪”,往往藏着最精妙的设计。
相关文章:
Python 字典键 “三变一” 之谜
开头:读者的“玄学”字典谜题 上周,朋友发来了一段让他抓耳挠腮的代码: >>> {True: foo, 1: bar, 1.0: baz} {True: baz} “我明明定义了布尔True、整数1、浮点数1.0三个键,结果字典里只剩True一个键,值…...
Spring Boot中HTTP连接池的配置与优化实践
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、HTTP连接池的核心价值 在微服务架构和分布式系统场景中,HTTP客户端频繁创建/断开连接会产生显著的性能损耗。通过连接池技术可以实现&#x…...
初识XML
初识XML <?xml version"1.0" encoding"utf-8" ?> <!--根标签只能有一个--> <!--第一行永远都是 <?xml version"1.0" encoding"utf-8" ?> 前面不允许出现任何其他东西,空格换行等均不行 --> &…...

element-ui分页的使用及修改样式
1.安装 npm install element-ui -S 2.在main.js中引入,这里是全部引入,也可以按需引入 import ElementUI from element-ui import element-ui/lib/theme-chalk/index.css Vue.use(ElementUI) 3.使用 layout"prev, pager, next, jumper" :jumpe…...
2025年第十六届蓝桥杯软件赛省赛C/C++大学A组个人解题
文章目录 题目A题目C:抽奖题目D:红黑树题目E:黑客题目F:好串的数目 https://www.dotcpp.com/oj/train/1166/ 题目A 找到第2025个素数 #include <iostream> #include <vector> using namespace std; vector<i…...
物理:人的记忆是由基本粒子构成的吗?
问题: 基因属于人体的一部分,记忆也是人体的一部分,那么为什么基因可以代际遗传,但是记忆却被清空重置。如果基因是由粒子构成,那么记忆是不是也应该由粒子构成?如果记忆是粒子构成的,那么能否说明记忆永恒,即使死亡了身体被分解了,那么只要保证其身体有关的所有粒子被…...
Memcached 的特性和使用场景介绍,以及集群搭建
以下是 Memcached 的特性和使用场景介绍,以及集群搭建的详细示例: 特性 高性能 内存存储:数据存储在内存中,读写速度极快。简单协议:使用基于文本的简单协议,通信高效。分布式架构 一致性哈希:采用一致性哈希算法,将数据均匀分布到多个节点,支持动态增减节点,减少数…...
uni-app,小程序中的addPhoneContact,保存联系人到手机通讯录
文章目录 方法详解简介 基本语法参数说明基础用法使用示例平台差异说明注意事项最佳实践 方法详解 简介 addPhoneContact是uni-app框架提供的一个实用API,用于向系统通讯录添加联系人信息。这个方法在需要将应用内的联系人信息快速保存到用户设备通讯录的场景下非…...

从数据中台到数据飞轮:数字化转型的演进之路
从数据中台到数据飞轮:数字化转型的演进之路 数据中台 数据中台是企业为整合内部和外部数据资源而构建的中介层,实现数据的统一管理、共享和高效利用,目标是打破信息孤岛,提高数据使用效率,支持业务决策和创新 实施成本…...
Spring Boot 注解详细解析:解锁高效开发的密钥
一、引言 Spring Boot 以其快速开发、自动配置等特性,成为构建 Java 应用程序的热门框架。而注解在 Spring Boot 中扮演着至关重要的角色,它们如同魔法指令,简化了配置流程,增强了代码的可读性与可维护性。本文将深入剖析 Spring…...

2025年5月-信息系统项目管理师高级-软考高项一般计算题
决策树和期望货币值 加权算法 自制和外购分析 沟通渠道 三点估算PERT 当其他条件一样时,npv越大越好...

zst-2001 上午题-历年真题 算法(5个内容)
回溯 算法 - 第1题 找合适的位置,如果没有位置就按B回家 d 分治 算法 - 第2题 b 算法 - 第3题 a 算法 - 第4题 划分一般就是分治 a 算法 - 第5题 分治 a 0-1背包 算法 - 第6题 c 算法 - 第7题 最小的为c 3100 c 算法 - 第8题 …...
【愚公系列】《Manus极简入门》036-物联网系统架构师:“万物互联师”
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! …...
3d关键点 可视化
目录 pygame pygame保存mp4 mayavi pygame import pygame from pygame.locals import * import numpy as np import sys# 初始化Pygame pygame.init() width, height 800, 600 screen pygame.display.set_mode((width, height)) clock pygame.time.Clock()# 生成示例数据…...

udp多点通信和心跳包
刷题 # UDP多点通信核心要点## 基础通信模式### 单播通信- 一对一通信方式- UDP默认通信模式- 地址指向具体目标主机### 广播通信- 一对多通信机制- 地址范围:xxx.xxx.xxx.255- 仅限局域网传输- 需设置SO_BROADCAST标志### 组播通信- 多对多群组通信- 地址范围&…...
什么是序列化与反序列化
序列化与反序列化:概念、作用及应用 一、基本定义 序列化(Serialization) 将 ** 对象的状态(数据、属性等)转换为可存储或传输的字节流(二进制或文本格式)** 的过程。 目的:使对象能…...

音视频学习:使用NDK编译FFmpeg动态库
1. 环境 1.1 基础配置 NDK 22b (r22b)FFmpeg 4.4Ubuntu 22.04 1.2 下载ffmpeg 官网提供了 .tar.xz 包,可以直接下载解压: wget https://ffmpeg.org/releases/ffmpeg-4.4.tar.xz tar -xvf ffmpeg-4.4.tar.xz cd ffmpeg-4.41.3 安装基础工具链 sudo …...

如何使用 Qwen3 实现 Agentic RAG?
今天,我们将学习如何部署由阿里巴巴最新Qwen 3驱动的Agentic RAG。 这里是我们的工具栈: CrewAI用于代理编排。 Firecrawl用于网络搜索。 LightningAI的LitServe用于部署。 顶部的视频展示了这一过程。 图表显示了我们的Agentic RAG流程࿱…...

相机、雷达标定工具,以及雷达自动标定的思路
本篇我们来看一下自动驾驶传感器配置一个非常重要的模块,也就是传感器的标定。这里主要是对我之前修改的功能包的使用进行一个介绍. 对应的资源也已经上传了,0积分下载 安装 首先整个项目是使用ros1来进行启动的,但是要想正常编译,需要先安装三个对应的…...

vsomeip环境搭建保姆级教程
vsomeip环境搭建保姆级教程 ubuntu环境搭建 {% links %} site: VMware搭建ubuntu保姆级教程 url: https://zhuanlan.zhihu.com/p/1903219373906327339 desc: flechazo image: https://q1.qlogo.cn/g?b=qq&nk=2861099&s=5 color: “#9d5b8b” {% endlinks %} vsomei…...
【工具记录分享】提取bilibili视频字幕
F12大法 教程很多 但方法比较统一 例快速提取视频字幕!适用B站、AI字幕等等。好用 - 哔哩哔哩 无脑小工具 哔哩哔哩B站字幕下载_在线字幕解析-飞鱼视频下载助手 把链接扔进去就会自动生成srt文件 需要txt可以配合: SRT转为TXT...

我的MCP相关配置记录
1.VSCode的Cline中的MCP {"mcpServers": {"github.com/modelcontextprotocol/servers/tree/main/src/github": {"autoApprove": [],"disabled": false,"timeout": 60,"command": "cmd","args&quo…...
systemd vs crontab:Linux 自动化运行系统的全面对比
在 Linux 系统运维和开发中,任务调度与服务管理 是不可或缺的一环。无论是定期备份、日志轮转,还是启动后台服务,自动化机制都能极大地提高系统的可靠性与效率。两种最常用的自动化工具是: crontab:传统的基于时间的任…...

我们来学nacos -- 集群nacos2.5.1mysql8.4
2.5.1集群搭建 架构下载解压到3个文件夹初始化数据库&数据迁移检查端口可用配置cluster.confapplication.properties 使用mysql8.4的jar启动db.num is null报错datasource错误成功 nginx反向代理集群查看 架构 其中包含3个nacos节点,然后一个负载均衡器代理3个…...
计算机网络核心技术解析:从基础架构到应用实践
计算机网络作为现代信息社会的基石,承载着全球数据交换与资源共享的核心功能。本文将从网络基础架构、核心协议、分层模型到实际应用场景,全面解析计算机网络的核心技术,并结合行业最新趋势,为读者构建系统的知识体系。 一、计算机…...
Spring Boot 基于 Cookie 实现单点登录:原理、实践与优化详解
前言 在多系统交互的应用场景中,单点登录(SSO)能够显著提升用户体验,减少重复登录的繁琐操作。基于 Cookie 的单点登录方案,凭借其简单直观、浏览器原生支持的特性,成为快速实现单点登录的有效方式。本文将…...

Rollup入门与进阶:为现代Web应用构建超小的打包文件
我们常常面临Webpack复杂配置或是Babel转译后的冗余代码,结果导致最终的包体积居高不下加载速度也变得异常缓慢,而在众多打包工具中Rollup作为一个轻量且高效的选择,正悄然改变着这一切,本文将带你深入了解这个令人惊艳的打包工具…...
pdf url 转 图片
背景:vue2.0需要把pdf转成图片,显示在url里面,使用pdfjs-dist来解决 步骤: 1、安装依赖包(我的项目是node12,安装太高版本会报错) npm i pdfjs-dist2.16.105 2、vue代码 <template><div class"main…...

专题四:综合练习( 找出所有子集的异或总和再求和)
以leetcode1863题为例 题目分析: 找到每个子集,然后子集中的元素异或之后全部相加 算法原理分析: 画决策树:第一层为这个子集有一个元素 第二层这个子集有两个元素 从上往下罗列,把所有子集都罗列出来…...

STM32 修炼手册
第一章 计算机体系结构(了解) 后续在板子上开发的时候,需要考虑是否有操作系统 方式一:有操作系统,通过c库通过os api操作硬件方式二:无操作系统, 通过c库通过固件库操作硬件 第二章 STM32开发板概述 板子/开发板&…...