资讯动态

Python字典入门指南:从键值对映射到高效查找

发布时间:2026/10/14 7:41:07 来源:尧图企业网站定制
很多人刚开始学Python学到列表、元组都能跟得上一到字典就开始犯迷糊。原因其实很直接列表、元组都是“按位置找值”位置就是0、1、2这种整数规律一眼就能看穿字典是“按关键字找值”关键字可以是字符串、整数语义上“名字”和“内容”直接对应。这种从“序号”到“名称”的思维切换对刚接触编程的人来说确实需要一个适应过程。我经常带新人入门被问到最多的一句话就是“字典到底能拿来干什么”我的回答很直接当你想根据一个名字、一个编号去查它对应的信息时字典就是Python里最顺手的工具。你可以把它想成手机通讯录里的分组标签报出“妈妈”立刻得到号码不用从头翻一遍列表。这篇文章不打算把字典的所有语法全罗列出来而是用几个轻量级例子把创建、读取、修改、遍历、常用方法过一遍再整理几个初学者最容易踩的坑。目标是让零基础的朋友也能跟着敲完敲完之后能自己造例子。本文用到的代码都基于Python 3.x版本还没装好Python环境的话建议先去官网下载稳定版安装包安装时记得勾选“Add Python to PATH”后面命令行操作会省很多事。1. 开始之前字典和列表的核心差别在哪里1.1 字典是“映射”不是“序列”列表、元组这类容器元素的身份是“下标”。下标是0、1、2、3是线性排下去的你告诉Python“我要第3个元素”它直接顺着位置走过去。字典不一样它存放的是“键: 值”这种成对数据键和值之间用冒号连接多对数据用逗号分开整体用花括号包起来。比如下面这个例子score {语文: 92, 数学: 88, 英语: 95}这里“语文”“数学”“英语”是键92、88、95是值。你想查数学成绩时报出“数学”这个键Python直接返回88这个动作在编程里叫“按键取值”。更重要的是键是唯一的同一个键重复出现时后面的值会覆盖前面的值。这一点很多初学者会忽略后面我会单独展开讲。1.2 查找效率的直观理解如果你只写过几百行代码可能感觉不到“效率”这个词到底意味着什么。等数据量变大之后体感差异会非常明显。列表查找一个元素最坏情况是一个一个比过去时间复杂度是O(n)字典查找是通过计算键的哈希值直接定位到存储位置绝大多数情况下是O(1)。我常给新人打一个比方列表是一摞按顺序排好的试卷老师要找某位同学的卷子只能从头一张张翻字典是一个贴好标签的档案柜每个标签写着名字老师直接走到对应抽屉前拉开就拿到了。同样是“查找”过程差着好几个数量级。所以从第一天起你就应该形成习惯能按名称或编号查内容的数据优先用字典别硬塞进列表里再用index慢慢找。这不仅是为了性能更是为了让代码读起来更自然、更接近人类思考问题的方式。2. 入门第一课创建字典和读取字典2.1 三种创建方式一次理清新手最常犯的错误是把创建方式记混。其实日常开发中常用的就三种不需要背太多。第一种直接写花括号。这也是最直观的方式student {name: 王小明, age: 12, class_name: 五年三班}键和值都是成对出现的中间用冒号每一对之间用逗号。注意我用了“class_name”而不是“class”因为“class”是Python的保留字直接当键写在花括号里其实没问题但后面如果用dict()来创建就会报语法错误为了统一习惯建议直接避开。第二种用dict()函数搭配关键字参数。这种方式写起来简洁但键不能加引号student dict(name王小明, age12) print(student) # 输出: {name: 王小明, age: 12}这里“name”和“age”是作为参数名传入的接收结果后键自动变成字符串。第三种从成对的数据序列转换。程序运行到一半从外部读进来的数据经常是成对结构这时候一行转换就行pairs [(name, 王小明), (age, 12)] student dict(pairs)比如从CSV文件读出的某一行数据或从数据库查询结果里取出的字段列表都很适合用这种方式转成字典。2.2 读取值方括号与get方法读取值是字典使用频率最高的操作。没有悬念最直接的写法是用方括号print(student[name]) # 输出 王小明 print(student[age]) # 输出 12但这里有一个新手最容易碰到的坑如果键不存在方括号会直接抛KeyError。比如你敲了student[score]程序会立刻红屏中断。想处理得更优雅就用get()方法print(student.get(score)) # 返回 None不报错 print(student.get(score, 0)) # 返回 0因为指定了默认值第一行适合“查一下有没有都不影响流程”的场景第二行适合“有就用没有就用备选值”的场景。我个人的习惯是能确定键一定存在时用方括号不能确定时用get。不要把两者混着乱用不然阅读代码的人需要猜你的意图会很累。2.3 修改、新增与删除字典是可变的可以原地修改。这个特性和列表类似和元组正好相反。新增一个键值对和修改一个已有键的值语法完全一样student[age] 13 # 修改已有键 student[city] 北京 # 新增键 print(student)如果键不存在赋值就是新增如果键已经存在赋值就是覆盖旧值。删除键值对可以用del语句del student[city]这个操作会直接移除“city”这个键以及它对应的值。不过要小心如果键不存在del同样会抛KeyError。想安全一点可以结合in运算符先判断if city in student: del student[city]3. 几个能直接练手的趣味小例子3.1 学生成绩登记与查询这里用一个最常见的学习场景来加深理解。假设你要管理几位同学的成绩存成字典后按名字查询scores { 小明: 92, 小红: 88, 小刚: 76 } name input(请输入学生姓名) if name in scores: print(f{name}的成绩是{scores[name]}) else: print(没有找到这位同学的成绩)这个例子里有两层理解重点。第一name in scores判断的是“键”是否存在不是“值”。第二从字典里取值的写法scores[name]name是一个变量它的值来自用户输入。很多初学者在初学时会把代码写成scores[name]那表示找键为字符串name的项而不是找变量name对应的值。这两个写法的区别非常关键建议亲手敲一遍对比输出结果。3.2 统计字符串中每个字符出现的次数这个例子在面试题和日常脚本里都很常见而且能很好地体现字典的核心价值临时记录“键与值”的对应关系。text hello world counter {} for ch in text: if ch in counter: counter[ch] counter[ch] 1 else: counter[ch] 1 print(counter)过程其实很朴素遍历每个字符如果这个字符以前没出现过就把它的计数初始化为1如果出现过了就把原来的计数加1。运行结果类似{h: 1, e: 1, l: 3, o: 2, : 1, w: 1, r: 1, d: 1}这个例子能帮助你理解“先判断键是否存在再决定是新增还是更新”这一核心套路。后面学了collections模块的Counter之后这种需求还有更简洁的写法但初学阶段用基础字典实现一遍收益是最大的。3.3 简易电话簿把姓名和电话号码存在一起再模拟一个查询循环phone_book { 妈妈: 138-0000-0001, 爸爸: 138-0000-0002, 小明: 138-0000-0003 } while True: key input(请输入要查询的名字输入exit退出) if key exit: break if key in phone_book: print(f{key}的电话是 {phone_book[key]}) else: print(通讯录里没有这个人)这个例子虽然简单但它把一个真实需求完整串起来了创建、判断、取值、循环退出。等你能不假思索写出这个程序时你对字典的基本操作就已经建立起了手感。4. 字典的常用方法与遍历技巧4.1 三种遍历姿势字典本身是“键值对”的集合遍历方式比列表多一些选择。最常用的有三种方向只遍历键、只遍历值、同时遍历键和值。student {name: 王小明, age: 12, city: 北京} # 默认遍历键 for k in student: print(k) # 遍历键值对 for k, v in student.items(): print(k, v)默认情况下直接for k in student拿到的就是键的集合这个写法最常用。.items()返回一组组键值对可以直接拆包成两个变量这也是我平时用得最多的方式。需要说明的是Python 3.7之后字典会保持插入顺序所以遍历出来的顺序和添加顺序一致这一点在调试的时候能减少很多困惑。4.2 合并字典与设置默认值两个字典合并Python 3.9之后可以直接用|运算符dict1 {a: 1, b: 2} dict2 {b: 3, c: 4} merged dict1 | dict2 print(merged) # {a: 1, b: 3, c: 4}当两个字典都有同一个键时右边的字典优先。这个规则记清楚面试里也常考。如果还停留在旧版本环境也可以用{**dict1, **dict2}效果一样。另一个很实用的小方法是setdefault()它的作用是“取不到的键就设置一个默认值再返回”。举例来说data {} data.setdefault(count, 0) print(data[count]) # 0很多人在写词频统计时会手动判断键是否存在用setdefault可以让代码少几行counter {} for ch in text: counter[ch] counter.setdefault(ch, 0) 1这里的逻辑是先取当前字符的计数值取不到就用0然后加1后再写回去。第一次遇到某个字符时setdefault还会顺手把键初始化为0后续循环就不再触碰这个逻辑。4.3 需要小心的清空与复制清空字典用clear()它会直接清掉所有键值对。复制字典有两种常见方式先看一个容易出错的例子original {a: 1} copy1 original copy1[b] 2 print(original) # {a: 1, b: 2}原字典也被改了这个现象初学者经常遇到原因在于copy1 original并没有创建新字典而是让两个变量指向同一个字典对象。想让复制出来的字典是独立的需要用.copy()方法original {a: 1} copy2 original.copy() copy2[b] 2 print(original) # {a: 1}原字典不受影响不过要注意.copy()是浅拷贝如果字典里的值是列表或嵌套字典修改内层内容时仍然会影响原字典。这个知识点新手阶段可以只知道结论后续学到可变对象时再深入理解。5. 初学者必须避开的几个坑5.1 键重复导致的数据覆盖这是初学者写字典时最容易踩的坑而且它不报错所以很难被察觉。你在创建字典时不小心写了同一个键两次后面的值会把前面的覆盖掉settings { theme: dark, font_size: 14, theme: light } print(settings) # {theme: light, font_size: 14}像这种代码如果数据是动态生成或者由用户输入拼出来的重复键可能藏在很隐蔽的位置。排查的时候可以用len(dict)与预期的键数量对比如果对不上赶紧检查是否有重复键。养成一种习惯把“键唯一”当作字典的基本纪律写代码时可以有意识地在心里默念“键是身份证号不是随便起的备注”。5.2 KeyError与NotImplementedError无关的报错处理KeyError可能是初学者接触的第一批异常之一。它的本质是“你找的键不在字典里”。除了用get()规避之外也可以用try/except主动捕获try: value data[missing] except KeyError: print(没有这个键做兜底处理)我见过不少新手为了防KeyError在每个取值的地方都套一层try/except这会导致代码非常啰嗦。简单场景优先考虑get()和in判断只有真正无法预测键是否存在、又有复杂的兜底逻辑时才适合用异常处理。还有一个容易被忽略的点在遍历字典的同时去修改字典比如在循环里删除某些键会触发RuntimeError。常见的报错信息是“dictionary changed size during iteration”。解决办法是先把需要删除的键收集到一个列表里循环结束之后再统一删除keys_to_delete [k for k, v in data.items() if v 0] for k in keys_to_delete: del data[k]5.3 可变对象不能当键字典的键要求是可哈希的因此列表、字典这类可变对象不能直接作为键。初学者在写嵌套结构时很容易写出类似下面的代码然后报TypeError# 错误示例 # bad_dict {[name]: 小明}解决办法有两个方向。一是改用元组作为键比如坐标点就非常适合用元组positions {(0, 0): 起点, (3, 5): 宝箱} print(positions[(0, 0)])二是重新审视数据结构如果发现自己真的想把列表当键通常说明问题的本质是另一个维度你可能需要的是一个按条件筛选键的列表而不是一个以列表为键的字典。5.4 键是否存在判断的是键而不是值这点前面提过但值得再说一次因为它太常见了。张三 in student_dict判断的是字典的键里有没有“张三”而不是值里有没有“张三”。如果你想判断某个值是否在字典中应该用张三 in student_dict.values()。初学者如果搞混这两个概念写出来的判断逻辑经常会和你预期的结果完全相反而且表面上看不出哪里有错。判断目标正确写法错误写法判断键是否存在name in dname in d.values()判断值是否存在张三 in d.values()张三 in d取出键对应的值d[name]d.name这张表我建议直接存下来遇到类似问题对照一眼即可。多说一句d.name这种写法在某些第三方库的类对象里是合法属性访问但在普通字典里不是不要混用。6. 几段适合抄作业的进阶小练习6.1 统计字符串里出现频率最高的单词把字典和列表配合起来能解决很多实际问题。比如统计一篇文章里出现次数最多的词words [苹果, 香蕉, 苹果, 橘子, 苹果, 香蕉] counter {} for w in words: counter[w] counter.get(w, 0) 1 # 找出出现次数最多的词 max_word max(counter, keycounter.get) print(max_word, counter[max_word])这里关键点在max(counter, keycounter.get)。counter在迭代时提供的是键key参数告诉max用每个键对应的值来比较大小最终返回的是值最大的那个键。这个写法很精炼面试笔试里经常遇到建议背下来并理解。6.2 用嵌套字典模拟一个简单的用户系统当字典的值还是字典时数据模型会更有表达力users { user001: {name: 小明, level: 3, points: 1200}, user002: {name: 小红, level: 5, points: 2300} } # 查询某个用户的信息 uid user001 if uid in users: info users[uid] print(info[name], info[level])这种结构在真实的Web后端、爬虫配置、游戏存档里非常常见。理解“值可以是任意类型包括另一个字典”这一点后你会发现自己能设计的数据结构立刻上了一个台阶。很多初学者习惯把所有字段拍平在一层结果代码里user001_name、user001_level这种变量名满天飞用嵌套字典之后逻辑清晰得多。6.3 按体重分组的小例子假设你有一批人的体重数据想按“偏瘦、正常、偏胖”分组people {小明: 45, 小红: 52, 小刚: 65, 小丽: 58} groups {偏瘦: [], 正常: [], 偏胖: []} for name, weight in people.items(): if weight 50: groups[偏瘦].append(name) elif weight 60: groups[正常].append(name) else: groups[偏胖].append(name) print(groups)这个例子的核心意义不在体重本身而在于展示“用字典存多个分组每个分组对应一个列表”这一通用模式。以后你做数据清洗、问卷分类、日志分桶时都会用到同样的思路。6.4 字典推导式用一行代码构造字典等你对基础写法足够熟练可以开始接触字典推导式。它能用一行代码生成字典语法上和列表推导式很像# key是数字value是该数字的平方 squares {x: x * x for x in range(1, 6)} print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}另一个常见场景是从已有字典里过滤出符合条件的项scores {小明: 92, 小红: 88, 小刚: 76} passed {k: v for k, v in scores.items() if v 80} print(passed) # {小明: 92, 小红: 88}字典推导式非常适合处理“从现有数据中批量生成新字典”的需求。整体难度比前面的例子稍高但不建议跳过因为很多真实项目代码里你会频繁见到它。7. 我的整理方法与学习建议7.1 先动手敲再谈理解字典这个知识点看视频看三天不如手敲三小时。我见过太多人收藏了无数教程实际打开解释器的时间寥寥无几。初学阶段建议在交互式环境里逐个测试今天学的几种创建方式、get()带不带默认值、in判断键还是值都可以随手写出来看结果。我个人的经验是每个小知识点花上十分钟敲三遍比一次性看完一整套视频记住的牢固得多。7.2 准备一个随手可查的“速查表”自己整理一张速查表比直接抄别人的更有价值。我的做法是建一个本地笔记按“创建、读取、修改、删除、遍历、常用方法”分组每个方法配一个最简单的示例。当我在项目里遇到“又要去查方法名”的时候打开笔记扫一眼就能定位。长期积累下来这份速查表会成为你Python路上最实用的资产之一。7.3 把字典当作思维模型去使用写代码写了一段时间之后你会发现字典不仅是一种语法更是一种思维模型。它鼓励你用“名称到内容”的方式组织数据让你的程序和现实世界保持对称。你提到“小明”就得到一个学生对象你提到“product_001”就得到商品详情这种一对一、一对多的关系在字典里都能自然表达。等到你将来接触JSON、数据库查询结果时会发现它们和字典的结构几乎一一对应那时候你就不会再对字典感到陌生了。我个人在实际教学中的体会是初学者第一次接触字典时不需要一次性把所有方法都背完。先把创建、读取、修改、遍历这四件事练熟把get()和in判断记住剩下的方法用到时查一下即可。等你在几个小例子里感受到“哦原来用字典查东西这么方便”后面再学嵌套字典、字典推导式、字典与JSON的转换都会顺理成章很多。现在就去打开你的Python环境把今天这几个例子亲手敲一遍吧。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑