python字典的常用方法与字典的嵌套
python字典的常用方法与字典的嵌套。和列表、字符串一样,字典也内置了很多方法供我们使用,调用方法时,写成字典名.方法名()的形式,字典名和方法名之间要用连接。下面的字典students以键值对的形式,保存了这次编程考试中所有同学的成绩。接下来我们以它为例,了解一下字典都有哪些常用方法吧~
字典常用方法
和列表、字符串一样,字典也内置了很多方法供我们使用,调用方法时,写成 字典名.方法名()
的形式,字典名和方法名之间要用 .
连接。
下面的字典 students
以 人名-成绩 键值对的形式,保存了这次编程考试中所有同学的成绩。接下来我们以它为例,了解一下字典都有哪些常用方法吧~
# 编程考试成绩
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
get()
在上一关中我们学到,可以通过 字典[键]
的方式获取字典中 键
对应的 值
。而当 键
不存在,程序会报错,这影响到我们后续代码的执行。
事实上,Python 为字典提供了一种更安全的查询方法,get()
方法。
将字典的键作为参数传入 get()
方法中,它就会帮我们查询字典中有没有这个键。如果存在的话,返回键对应的值;不存在的话,默认返回 None
。
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
print(students.get('林黛玉'))
# 输出:95
print(students.get('小小'))
# 输出:None
keys()
keys()
方法则可以获取字典中所有的 键。
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
names = students.keys()
print(names)
# 输出:dict_keys(['林黛玉', '薛宝钗', '贾宝玉', '袭人'])
print(type(names))
# 输出:<class 'dict_keys'>
可以看到,在 Python3 中 keys()
方法返回的是一个特殊类型 dict_keys
。
当我们将 students.keys()
的结果保存到变量 names
后,可以通过成员运算符 in
判断某个元素在不在里面,也可以使用 for
循环遍历它。
if '林黛玉' in names:
print('林黛玉的成绩已录入')
# 输出:林黛玉的成绩已录入
for name in names:
print(name)
# 输出:林黛玉 薛宝钗 贾宝玉 袭人
但它是不能被索引的。如果想通过索引访问元素,需要先用 list()
函数将它转换成列表类型,再进行访问。
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
names = list(students.keys())
print(names[0])
# 输出:林黛玉
values()
与 keys()
方法相对应,我们可以通过 values()
方法获取字典中所有的 值。
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
scores = students.values()
print(scores)
# 输出:dict_values([95, 93, 78, 85])
print(type(scores))
# 输出:<class 'dict_values'>
values()
方法返回的也是一个特殊类型,不可索引,可遍历,所以一般搭配 for
循环使用。
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
scores = students.values()
for score in scores:
print(score)
# 输出:95 93 78 85
items()
除了获取所有的键、值,我们也可以通过 items()
方法,一次性获取字典中所有的 键值对 ,其中每个键值对都是一个形如 (键, 值)
的元组。items()
方法返回的也是一个特殊类型,不可索引,可遍历。
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
student = students.items()
print(student)
# 输出:dict_items([('林黛玉', 95), ('薛宝钗', 93), ('贾宝玉', 78), ('袭人', 85)])
print(type(student))
# 输出:<class 'dict_items'>
(键, 值)
元组构成的序列应该怎么遍历呢?老师给你准备了一个例子。在下面的 for
循环中,name
和 score
分别取到了每个键值对中的键、值。
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
# 以 name, score 遍历 students 中键值对
for name, score in students.items():
print('{}的分数是:{}'.format(name, score))
# 输出:
# 林黛玉的分数是:95
# 薛宝钗的分数是:93
# 贾宝玉的分数是:78
# 袭人的分数是:85
上面是在使用字典时最常用的几个方法,我们再来归纳总结一下:
编程练习
字典 students
保存了本次编程考试成绩。我们需要根据每个人的成绩,写下不同的评语。
- 分数大于 90:打印 xxx 考得很好继续保持;
- 分数在 80 和 90 之间:打印 xxx 考得不错继续加油;
- 分数小于等于 80:打印 xxx 考得不行下次努力。
其中 xxx 表示人名。
趁热打铁,下面请你用 for
循环和 items()
方法遍历字典完成任务吧~
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
# 以 name, score 遍历 students 中键值对
优化后代码:
students = {
'林黛玉': 95,
'薛宝钗': 93,
'贾宝玉': 78,
'袭人': 85
}
# 以 name, score 遍历 students 中键值对
for name,score in students.items():
if score > 90:
print('{}考得很好继续保持'.format(name))
elif score > 80:
print('{}考得不错继续加油'.format(name))
else:
print('{}考得不行下次努力'.format(name))
# 代码输出结果为:
# 林黛玉考得很好继续保持
# 薛宝钗考得很好继续保持
# 贾宝玉考得不行下次努力
# 袭人考得不错继续加油
字典的嵌套
学了那么多字典的常用方法,还是要落回到实际问题和应用上来。
在编程世界里,每一种数据类型,都是为了更好地表示现实世界中的信息:我们用 整数
、浮点数
类型描述数字,用 字符串
类型保存文本,用 布尔
类型表示真假的概念,用 列表
类型存放大量有顺序的数据……这些类型也可以结合起来使用,表示复杂的信息。
🤔️ 那 字典
类型适合表示现实中的哪些信息呢?它和其它数据类型可以结合起来使用吗?下面让老师带你走进几个生活中的场景,看看字典与列表间是怎样相互配合表示数据的。
列表中嵌套字典
我们来看看第一个场景:保存编程考试的成绩。
- 编程一班:林黛玉 95 分;贾宝玉 78 分;
- 编程二班:薛宝钗 93 分;袭人 85 分。
把同学的成绩看成 姓名-成绩 键值对的话,相信你很快就能写出这样的代码:
# 编程一班
class_1_score = {'林黛玉': 95, '贾宝玉': 78}
# 编程二班
class_2_score = {'薛宝钗': 93, '袭人': 85}
但这么做有个很麻烦的地方:班级数量一多,变量也会增多,很不方便管理。为了统一管理多个字典变量,我们可以把它们放进一个列表 scores
中,形成 列表中嵌套字典 的结构。这样我们就不用为每个班级单独定义字典变量了~
scores = [
# 编程一班
{'林黛玉': 95, '贾宝玉': 78},
# 编程二班
{'薛宝钗': 93, '袭人': 85}
]
在访问这种嵌套结构的内层数据时,需要按照它的 层级 一步一步访问。比如我们要获取林黛玉的成绩,要先通过索引,访问到列表 scores
中保存的第一个字典。
print(scores[0])
# 输出:{'林黛玉': 95, '贾宝玉': 78}
再通过 '林黛玉'
键,就能获取到她的成绩啦。
print(scores[0]['林黛玉'])
# 输出:95
我们来用一张图看一下列表 scores
的结构:
遍历时也是一样的道理,需要按照 层级关系,编写一个双重循环,在外层循环里遍历外层结构,内层循环里遍历内层结构。比如我们可以这样打印出每位同学的成绩:
scores = [
# 编程一班
{'林黛玉': 95, '贾宝玉': 78},
# 编程二班
{'薛宝钗': 93, '袭人': 85}
]
# 遍历列表 scores 中每个班级成绩册
for class_score in scores:
# 遍历成绩册中每位同学对应分数
for score in class_score.values():
print(score)
# 输出:95 78 93 85
列表中能嵌套字典,那字典中可以嵌套列表吗?
答案是可以的~字典类型中,每个 键
对应的 值
可以是各种各样的数据类型。之前我们已经学习过了值是 整数
、浮点数
、字符串
类型的例子,其实,字典的值也可以是 列表
、元组
,甚至是 字典
这样复杂结构的类型。
字典中嵌套列表
我们来看看第二个场景:保存班级名册。
- 编程一班:林黛玉、贾宝玉;
- 编程二班:薛宝钗、袭人。
列表类型很适合保存大量、有序的数据,所以我们可以为每个班级创建一个列表变量,保存班里同学的名字。
# 编程一班
class_1 = ['林黛玉', '贾宝玉']
# 编程二班
class_2 = ['薛宝钗', '袭人']
😵 但这样会遇到同样的问题:班级数量增多时,很难统一管理这些变量。那该如何把这些数据整合起来呢?
由于班级和它的名册之间,可以看成 班级-名册 的键值对,所以我们可以创建一个字典 students
,把它们整合起来,形成 字典中嵌套列表 的结构。这样一来不用专门为每个列表取变量名,二来可以通过易读易懂的键,方便地访问某个班级对应的名册。
students = {
'编程一班': ['林黛玉', '贾宝玉'],
'编程二班': ['薛宝钗', '袭人']
}
和刚刚学习的 列表中嵌套字典 结构一样,对于在 字典中嵌套列表 的 students
,也需要一层一层地去访问内部数据。比如我们可以通过 '编程一班'
键访问到它的名册。进一步地,通过索引 0
获取第一位同学的名字。
print(students['编程一班'])
# 输出:['林黛玉', '贾宝玉']
print(students['编程一班'][0])
# 输出:林黛玉
如果想打印出每位同学的名字,则可以写成这样的双重循环,在外层遍历每个班级的名册,在内层遍历名册中每个名字。
students = {
'编程一班': ['林黛玉', '贾宝玉'],
'编程二班': ['薛宝钗', '袭人']
}
# 遍历每个班级对应的名册
for names in students.values():
# 遍历名册中每个名字
for name in names:
print(name)
# 输出:林黛玉 贾宝玉 薛宝钗 袭人
编程练习
黄帮主临时来编程一班代课,想知道 袭人 在不在一班。你能编程帮他完成判断吗?
要求:若袭人在一班,打印 在编程一班,否则打印 不在编程一班。
提示:可以使用成员运算符
in
判断某个元素在不在列表里。
students = {
'编程一班': ['林黛玉', '贾宝玉'],
'编程二班': ['薛宝钗', '袭人']
}
编程后:
students = {
'编程一班': ['林黛玉', '贾宝玉'],
'编程二班': ['薛宝钗', '袭人']
}
if '袭人' in students.get('编程一班'):
# if '袭人' in students.get['编程一班']:
print('在编程一班')
else:
print('不在编程一班')
刚刚我们说了,字典的值可以是字典类型。那这样的结构有什么例子吗?下面我们来看看第三个场景。
字典中嵌套字典
假设我们需要保存这样一本单词书:
- apple - 释义:苹果;词性:名词;
- grape - 释义:葡萄;词性:名词。
可以看到单词书里每个单词都有两个类别的信息,这些信息可以看成 类别-内容 的键值对。所以我们可以为每个单词创建一个字典类型变量,保存单词信息。
apple = {'释义': '苹果', '词性': '名词'}
grape = {'释义': '葡萄', '词性': '名词'}
一本单词书里有很多单词,该如何表示这些单词都属于同一本单词书呢?很简单,由于每个单词和它的信息又可以看成 单词-信息 的键值对,所以我们可以用 字典
把这些单词整合起来,形成 字典中嵌套字典 的结构。
dictionary = {
'apple': {'释义': '苹果', '词性': '名词'},
'grape': {'释义': '葡萄', '词性': '名词'}
}
获取单词 apple 的释义时,也是一样的道理,需要按照 层级 一层一层地访问,先通过 'apple'
键访问到它的信息,再通过 '释义'
键获取到它的释义。
print(dictionary['apple'])
# 输出:{'释义': '苹果', '词性': '名词'}
print(dictionary['apple']['释义'])
# 输出:苹果
如果想按照 释义-词性
的格式,按行打印出每个单词对应的信息,我们可以写一个 for
循环,遍历 dictionary
字典中每个单词。
# 遍历每个单词对应的信息
for infos in dictionary.values():
# 获取释义
meaning = infos['释义']
# 获取词性
pos = infos['词性']
print('{}-{}'.format(meaning, pos))
# 输出:
# 苹果-名词
# 葡萄-名词
编程练习
字典 dictionary
以 单词-信息 键值对的形式表示一本单词书。
请你使用字典的 keys()
方法,统计这本书有多少个单词,并按照 单词书里有 xxx 个单词 的格式打印出来吧。
提示:可以使用
list()
函数将keys()
方法获取到的结果转换成列表类型,再统计单词个数。
dictionary = {
'apple': {'释义': '苹果', '词性': '名词'},
'grape': {'释义': '葡萄', '词性': '名词'},
'eat': {'释义': '吃', '词性': '动词'},
'big': {'释义': '大的', '词性': '形容词'}
}
# 获取单词书 dictionary 中的单词列表
# 单词列表为:['apple', 'grape', 'eat', 'big']
# 获取 word_list 的长度,即为单词个数
优化后的代码为:
dictionary = {
'apple': {'释义': '苹果', '词性': '名词'},
'grape': {'释义': '葡萄', '词性': '名词'},
'eat': {'释义': '吃', '词性': '动词'},
'big': {'释义': '大的', '词性': '形容词'}
}
# 获取单词书 dictionary 中的单词列表
# 单词列表为:['apple', 'grape', 'eat', 'big']
word_list = len(dictionary.keys())
# 获取 word_list 的长度,即为单词个数
print('单词书里有{}个单词'.format(word_list))
# 输出为:
# 单词书里有4个单词
编程练习二_摇骰子
大家肯定都摇过 🎲,我们知道一个骰子有六个面,分别对应 1-6 六个数字,这六个数字出现的概率是一样的,都是六分之一(0.166666...)。
还记得我们学过的 random
模块吗?为 random.choice()
函数传入一个非空序列,它会从中随机选取一个元素并返回。
接下来请你使用 random.choice()
函数模拟摇骰子的过程,统计每个数字出现的次数,并按照 数字 x 出现的频率为 xxx 的格式,打印出每个数字出现的频率吧。
提示:可以通过
数字出现次数 / 摇骰子总次数
计算出每个数字出现的频率。
# 导入 random 模块
import random
counts = {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0}
# 取出 counts 中所有键,并转换成列表类型
nums = ???
# 摇骰子次数
times = 5000
# 次数越多,每个数字出现的频率越接近于它的概率
# 你可以改成更大的数字试试,但耗时会更长
# 模拟摇骰子的过程并计数
# 打印每个数字出现的频率
代码优化完后:
# 导入 random 模块
import random
counts = {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0}
# 取出 counts 中所有键,并转换成列表类型
# 摇骰子次数
times = 5000
# 次数越多,每个数字出现的频率越接近于它的概率
# 你可以改成更大的数字试试,但耗时会更长
# 模拟摇骰子的过程并计数
for i in range(times):
nums = random.choice(list(counts))
# 灵活的方法
counts[nums] = counts[nums] + 1
# 笨方法
# if nums == '1':
# counts['1'] = counts['1'] + 1
# elif nums == '2':
# counts['2'] = counts['2'] + 1
# elif nums == '3':
# counts['3'] = counts['3'] + 1
# elif nums == '4':
# counts['4'] = counts['4'] + 1
# elif nums == '5':
# counts['5'] = counts['5'] + 1
# else:
# counts['6'] = counts['6'] + 1
# print(counts)
# 打印每个数字出现的频率
for i in counts:
chance = counts[i] / times
print('数字{}出现的概率为{}'.format(i, chance))
编程练习三:社团迎新会
又到了一年一度的社团招新季,编程社、话剧团和读书会这三个社团,计划一同举办社团迎新活动,欢迎新加入的小伙伴。
迎新会海报上,需要打印出各个社团的基本信息。字典 associations_dict
中,以 字典嵌套字典 的结构储存了各个社团的基本信息。下面请你按如下格式将社团信息打印出来:
参会社团信息:
------------
名称:编程社
社长:黄帮主
副社长:小贝
------------
名称:话剧团
社长:柚子
副社长:柠檬
------------
名称:读书会
社长:小林
副社长:多多
注意:由于 Python 中字典元素具有无序性,你的输出的顺序可能跟老师给出的范例不一样,因此本道题仅检查输出格式,不要求顺序完全相同。
associations = {
'编程社': {'社长': '黄帮主', '副社长': '小贝'},
'话剧团': {'社长': '柚子', '副社长': '柠檬'},
'读书会': {'社长': '小林', '副社长': '多多'}
}
print('参会社团信息:')
# 以 association, infos 遍历 associations
for ???, ??? in ???:
# 打印分割线
print('------------')
# 打印社团名称
# 以 title, name 遍历 infos
优化后的代码与输出为:
associations = {
'编程社': {'社长': '黄帮主', '副社长': '小贝'},
'话剧团': {'社长': '柚子', '副社长': '柠檬'},
'读书会': {'社长': '小林', '副社长': '多多'}
}
print('参会社团信息:')
# 以 association, infos 遍历 associations
for association,infos in associations.items():
# 打印分割线
print('------------')
# 打印社团名称
print('名称:{}'.format(association))
# 以 title, name 遍历 infos
for title,name in infos.items():
print('{}:{}'.format(title,name))
# 输出效果为:
# 参会社团信息:
# ------------
# 名称:编程社
# 社长:黄帮主
# 副社长:小贝
# ------------
# 名称:话剧团
# 社长:柚子
# 副社长:柠檬
# ------------
# 名称:读书会
# 社长:小林
# 副社长:多多
看完了上面几个例子,我们可以总结一下什么时候适合使用列表类型存储数据,什么时候又适合用字典存储:
如果每个元素间是并列关系,或者有先后顺序,适合用 列表
存储。
# 自然数
list1 = [0, 1, 2, 3]
# 学生名字
list2 = ['林黛玉', '贾宝玉', '薛宝钗', '袭人']
# 考试成绩
list3 = [95, 78, 93, 85]
如果数据与数据之间存在对应关系,则适合用 字典
存储。
# 单词-信息
apple = {'释义': '苹果', '词性': '名词'}
# 学生-成绩
class_1_score = {'林黛玉': 95, '贾宝玉': 78}
# 人-年龄
age = {'闻闻': 23, '小贝': 22}
当然,现实生活中的数据往往是复杂的,这时我们可以根据数据的特点,将两个类型结合起来。不同的数据类型,就像是“武器库”中各式各样的“武器”。每种“武器”都有自己的效果,我们要合理利用,才能充分发挥它们的优势!
如果你想知道如何在现实生活中运用各类“武器”,那一定不要错过选修内容中的进阶实操项目 游戏抽卡模拟器。在那里,我会带你运用模块、字典知识,从零开始编写一款抽卡模拟器,并为你拓展游戏“保底机制”实现原理。٩(˃̶͈̀௰˂̶͈́)و 相信完成项目后,你会对自己平时玩的游戏有更深刻的理解。
下章预告:
从下章开始,我们将走进 面向对象编程
,了解什么是 对象
,学会分析 对象
的共性,把这些共性抽象出来。在此基础上,我们还将学习如何为每一个不同的个体赋予它独有的个性。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)