【写在前面】为进一步提高自己的python代码能力,打算把几本经典书籍重新过一遍,形成系统的知识体系,同时适当记录一些学习笔记,我尽量及时更新!先从经典的《Python编程:从入门到实战》书籍开始吧。有问题欢迎在评论区讨论,互相学习,good good study,day day up!上一篇文章《Python编程:从入门到实战》(第2版)学习笔记 第5章 if语句。在本章中,你将学习Python字典以及如何访问和修改字典。字典可存储的信息量几乎不受限制,有存储字典的列表、存储列表的字典和存储字典的字典。
【特别说明】这是第二版的《Python编程:从入门到实战》,书本的Python版本是3.7.2,我自己运行代码的环境是3.7.0,不同Python版本的功能不同。
来源:《Python编程:从入门到实战》(第2版),侵权删!
下面是一个简单的字典,存储了有关特定外星人的信息:
>>> alien_0 = {'color': 'green', 'points': 5} #字典alien_0存储了外星人的颜色和点数
>>> print(alien_0['color'])
>>> print(alien_0['points'])
print语句访问并打印这些信息,如下:
green
5
在Python中字典用花括号{}中的一系列键值对表示。每个键都与一个值相关联,你可以使用键来访问对应的值。与键相关联的值可以是数字、字符串、列表乃至字典等任何Python对象。键和值之间用冒号分隔,而键值对之间用逗号分隔。在字典中可以存储任意个键值对。
最简单的字典只有一个键值对:
alien_0 = {'color': 'green'} #字符串'color'是一个键,对应的值为'green'
要获取与键相关联的值,可依次指定字典名和放在方括号内的键:
>>> alien_0 = {'color': 'green'}
>>> print(alien_0['color'])
返回字典alien_0中与键'color'对应的值:
green
现在回到最初的字典alien_0,如果玩家射杀了这个外星人,可以使用下面的代码来确定玩家应获得多少个点:
>>> alien_0 = {'color': 'green', 'points': 5}
>>> new_points = alien_0['points'] #获取与键'points'相关联的值,存储在变量new_points中
>>> print(f"You just earned {new_points} points!")
打印信息,指出玩家获得了多少个点:
You just earned 5 points!
字典是一种动态结构,可随时添加键值对,需要指定字典名、用方括号括起的键和相关联的值。
下面在字典alien_0中添加两项信息:外星人的x坐标和y坐标。我们将这个外星人放在屏幕左边缘,且离屏幕上边缘25像素的地方。假设屏幕坐标系的原点通常为左上角:
>>> alien_0 = {'color': 'green', 'points': 5}
>>> print(alien_0)
>>> alien_0['x_position'] = 0 #添加新的键值对
>>> alien_0['y_position'] = 25
>>> print(alien_0)
第1版书本的输出如下(这是python3.5.0的输出):
{'color': 'green', 'points': 5}
{'color': 'green', 'points': 5, 'y_position': 25, 'x_position': 0} 【注意:在Python3.7中,字典中元素的排列顺序和定义时相同,在打印和遍历元素时会体现这一点。】
自己跑的代码输出如下(和第2版输出一样):
可使用一对空的花括号定义一个空字典。
>>> alien_0 = {} #定义空字典alien_0
>>> alien_0['color'] = 'green' #添加颜色
>>> alien_0['points'] = 5 #添加点数
>>> print(alien_0)
输出:
{'color': 'green', 'points': 5}
使用字典来存储用户提供的数据或在编写能自动生成大量键值对的代码时,通常都需要先定义一个空字典。
要修改字典中的值,可依次指定字典名、用方括号括起的键以及与该键相关联的新值。例如,将一个外星人从绿色改为黄色:
>>> alien_0 = {'color': 'green'}
>>> print(f"The alien is {alien_0['color']}.")
>>> alien_0['color'] = 'yellow' #将与键'color'对应的值改为'yellow'
>>> print(f"The alien is now {alien_0['color']}.")
输出表明,这个外星人确实从绿色变成了黄色:
The alien is green.
The alien is now yellow.
来看一个更有趣的例子:对一个能够以不同速度移动的外星人的位置进行跟踪。为此,我们将存储该外星人的当前速度,并据此确定该外星人将向右移动多远:
>>> alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'} #定义了一个外星人
>>> print(f"Original x-position: {str(alien_0['x_position']}") #打印x_position的初始值
>>> # 向右移动外星人
>>> # 使用if-elif-else结构来确定外星人应向右移动多远
>>> if alien_0['speed'] == 'slow':
>>> x_increment = 1
>>> elif alien_0['speed'] == 'medium':
>>> x_increment = 2
>>> else:
>>> # 这个外星人的速度一定很快
>>> x_increment = 3
>>> # 新位置等于旧位置加上移动距离
>>> alien_0['x_position'] = alien_0['x_position'] + x_increment
>>> print(f"New x-position: {alien_0['x_position']}")
输出:
Original x-position: 0
New x-position: 2
对于字典中不需要的信息,可使用del语句彻底删除键值对,必须指定字典名和要删除的键。
从字典alien_0中删除键'points'及其值:
>>> alien_0 = {'color': 'green', 'points': 5}
>>> print(alien_0)
>>> del alien_0['points']
>>> print(alien_0)
输出:
{'color': 'green', 'points': 5}
{'color': 'green'}
注意 删除的键值对永远消失了。
在前面的示例中,字典存储的是一个对象(游戏中的一个外星人)的多种信息,但你也可以使用字典来存储众多对象的同一种信息。例如,假设你调查很多人最喜欢的编程语言,可使用一个字典来存储这种简单调查的结果:
>>> favorite_languages = {
>>> 'jen': 'python',
>>> 'sarah': 'c',
>>> 'edward': 'ruby',
>>> 'phil': 'python',
>>> }
注意 对于较长的列表和字典,大多数编辑器都有以类似方式设置其格式的功能:在花括号中按回车键,在下一行缩进4个空格,输入键值对后加一个逗号。一种不错的做法是在最后一个键值对后面也加上逗号,为以后在下一行添加键值对做好准备。
给定被调查者的名字,可使用这个字典轻松地获悉他喜欢的语言:
>>> favorite_languages = {
>>> 'jen': 'python',
>>> 'sarah': 'c',
>>> 'edward': 'ruby',
>>> 'phil': 'python',
>>> }
>>> languages = favorite_languages['sarah'].title()
>>> print(f"Sarah's favorite language is {languages}.")
输出:
Sarah's favorite language is C.
使用放在方括号内的键从字典中获取感兴趣的值时,可能会引发问题:如果指定的键不存在就会出错。
如果你要求获取外星人的分数,而这个外星人没有分数,会报错:
>>> alien_0 = {'color': 'green', 'speed': 'slow'}
>>> print(alien_0['points'])
这将导致Python显示traceback,指出存在键值错误(KeyError):
Traceback (most recent call last):
File "alien_no_points.py", line 2, in
print(alien_0['points'])
KeyError: 'points'
第10章将详细介绍如何处理类似的错误,但就字典而言,可使用方法get() 在指定的键不存在时返回一个默认值,从而避免这样的错误。
方法get() 的第一个参数用于指定键,是必不可少的;第二个参数为指定的键不存在时要返回的值,是可选的:
>>> alien_0 = {'color': 'green', 'speed': 'slow'}
>>> point_value = alien_0.get('points', 'No point value assigned.')
>>> print(point_value)
如果字典中有键'points' ,将获得与之相关联的值;如果没有,将获得指定的默认值。虽然这里没有键'points' ,但将获得一条清晰的消息,不会引发错误:
No point value assigned.
如果指定的键有可能不存在,应考虑使用方法get() ,而不要使用方括号表示法。
注意 调用get() 时,如果没有指定第二个参数且指定的键不存在,Python将返回值None 。这个特殊值表示没有相应的值。None 并非错误,而是一个表示所需值不存在的特殊值,第8章将介绍它的其他用途。
一个Python字典可能包含几个或者数百万个键—值对。Python支持对字典遍历,有多种遍历字典的方式:可遍历字典的所有键值对、键或值。
先来看一个新字典,它用于存储有关网站用户的信息,存储一名用户的用户名、名和姓:
>>> user_0 = {
>>> 'username': 'efermi',
>>> 'first': 'enrico',
>>> 'last': 'fermi',
>>> }
如果要获悉该用户字典中的所有信息,可以使用一个for循环来遍历这个字典:
>>> for key, value in user_0.items():
>>> print(f"\nKey: {key}")
>>> print(f"Value: {value}")
for key, value in user_0.items()声明两个变量,用于存储键值对中的键和值,这两个变量可使用任何名称,for k, v in user_0.items()也可以。使用方法items()它返回一个键值对列表。输出:
Key: username
Value: efermi
Key: first
Value: enrico
Key: last
Value: fermi
我的输出:
在6.2.6节的示例中,字典存储的是不同人的同一种信息,包含每个人的姓名和喜欢的编程语言。由于其中的键都是人名,而值都是语言,因此在循环中使用变量name和language,而不是key和value,这让人更容易明白循环的作用:
>>> favorite_languages = {
>>> 'jen': 'python',
>>> 'sarah': 'c',
>>> 'edward': 'ruby',
>>> 'phil': 'python',
>>> }
>>> for name, language in favorite_languages.items(): #遍历,将键存储在变量name中,而将值存储在变量language中
>>> print(f"{name.title() }'s favorite language is {language.title()}.")
上面代码将全部调查结果显示出来了:
Jen's favorite language is Python.
Sarah's favorite language is C.
Phil's favorite language is Python.
Edward's favorite language is Ruby.
即便字典存储的是上千乃至上百万人的调查结果,循环也管用。
在不需要使用字典中的值时,方法keys()很有用。下面来遍历字典favorite_languages,并将每个被调查者的名字都打印出来:
>>> favorite_languages = {
>>> 'jen': 'python',
>>> 'sarah': 'c',
>>> 'edward': 'ruby',
>>> 'phil': 'python',
>>> }
>>> for name in favorite_languages.keys(): #提取字典的所有键
>>> print(name.title())
输出:
Jen
Sarah
Phil
Edward
遍历字典时,会默认遍历所有的键,因此,.key()可以省略,上述代码的for name in favorite_languages.keys():替换为for name in favorite_languages:,输出不变。
在这种循环中,可使用当前键来访问对应的值。下面打印两条消息,指出两位朋友喜欢的语言:
>>> friends = ['phil', 'sarah']
>>> for name in favorite_languages.keys():
>>> print(f"Hi {name.title()}.")
>>>
>>> if name in friends: #检查当前的名字是否在列表friends中
>>> languages = favorite_languages[name].title()
>>> print(f"\t{name.title()} , I see you love {languages}! ")
输出如下:
Hi Jen.
Hi Sarah.
Sarah, I see you love C!
Hi Edward.
Hi Phil.
Phil, I see you love Python!
还可以使用keys()确定Erin是否接受了调查:
>>> if 'erin' not in favorite_languages.keys():
>>> print("Erin, please take our poll!")
输出:
Erin, please take our poll!
从Python3.7开始,遍历字典时将按照插入的顺序返回其中的元素。
要以特定的顺序返回元素,一种办法是在for循环中对返回的键进行排序,可使用函数sorted()来获取按特定顺序排列的键列表的副本:
>>> favorite_languages = {
>>> 'jen': 'python',
>>> 'sarah': 'c',
>>> 'edward': 'ruby',
>>> 'phil': 'python',
>>> }
>>> for name in sorted(favorite_languages.keys()):
>>> print(f"{name.title() }, thank you for taking the poll.")
这条for语句对方法dictionary.keys()的结果调用了函数sorted(),这让Python列出字典中的所有键,并在遍历前对这个列表进行排序。输出表明,按顺序显示了所有被调查者的名字:
Edward, thank you for taking the poll.
Jen, thank you for taking the poll.
Phil, thank you for taking the poll.
Sarah, thank you for taking the poll.
如果你感兴趣的主要是字典包含的值,可使用方法values(),它返回一个值列表,而不包含任何键。例如,我们想获得只包含被调查者选择的各种语言的列表:
>>> print("The following languages have been mentioned:")
>>> for language in favorite_languages.values():
>>> print(language.title())
输出:
The following languages have been mentioned:
Python
C
Ruby
Python
这提取字典中所有的值,而没有考虑是否重复。如果希望剔除重复项,可使用集合(set)。注意可使用一对花括号直接创建集合,并在其中用逗号分割元素,集合不会以特定顺序存储元素。集合和字典都是花括号定义的,当花括号内没有键值对时,定义的很可能是集合。
集合类似于列表,但每个元素都必须是独一无二的:修改for language in favorite_languages.values():为for language in set(favorite_languages.values()):
结果是一个不重复的列表,列出了被调查者提及的所有语言:
The following languages have been mentioned:
Python
C
Ruby
将一系列字典存储在列表中或将列表作为值存储在字典中,称为嵌套。你可在列表中嵌套字典、在字典中嵌套列表或者字典。
字典alien_0包含一个外星人的各种信息,但无法存储第二个外星人的信息。管理成群的外星人的一种办法是创建一个外星人列表。下面创建一个包含三个外星人的列表:
>>> alien_0 = {'color': 'green', 'points': 5}
>>> alien_1 = {'color': 'yellow', 'points': 10}
>>> alien_2 = {'color': 'red', 'points': 15}
>>> aliens = [alien_0, alien_1, alien_2]
>>> for alien in aliens:
>>> print(alien)
输出:
{'color': 'green', 'points': 5}
{'color': 'yellow', 'points': 10}
{'color': 'red', 'points': 15}
使用range()生成了30个外星人:
>>> aliens = [] # 创建空列表
>>> # 创建30个绿色的外星人
>>> for alien_number in range(30): #每次循环都创建一个外星人
>>> new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
>>> aliens.append(new_alien)
>>>
>>> # 显示前五个外星人
>>> for alien in aliens[:5]: #切片
>>> print(alien)
>>> print("...")
>>> print(f"Total number of aliens: {len(aliens)}")
输出:
{ 'color': 'green', 'points': 5,'speed': 'slow'}
{ 'color': 'green', 'points': 5,'speed': 'slow'}
{ 'color': 'green', 'points': 5,'speed': 'slow'}
{ 'color': 'green', 'points': 5,'speed': 'slow'}
{ 'color': 'green', 'points': 5,'speed': 'slow'}
...
Total number of aliens: 30
这些外星人都具有相同的特征,但Python看来每个外星人都是独立的,可以独立修改,可使用for循环和if语句来修改某些外星人的颜色。 例如,将前三个外星人修改为黄色的、速度为中等且值10个点:
>>> for alien in aliens[0:3]:
>>> if alien['color'] == 'green':
>>> alien['color'] = 'yellow'
>>> alien['speed'] = 'medium'
>>> alien['points'] = 10
输出如下:
{ 'color': 'yellow', 'points': 10,'speed': 'medium'}
{ 'color': 'yellow', 'points': 10,'speed': 'medium'}
{ 'color': 'yellow', 'points': 10,'speed': 'medium'}
{ 'color': 'green', 'points': 5,'speed': 'slow'}
{ 'color': 'green', 'points': 5,'speed': 'slow'}
...
进一步扩展添加一个elif代码块,将黄色外星人改为移动速度快且值15个点的红色外星人(这里只列出了循环):
>>> for alien in aliens[0:3]:
>>> if alien['color'] == 'green':
>>> alien['color'] = 'yellow'
>>> alien['speed'] = 'medium'
>>> alien['points'] = 10
>>> elif alien['color'] == 'yellow':
>>> alien['color'] = 'red'
>>> alien['speed'] = 'fast'
>>> alien['points'] = 15
有时需要将列表存储在字典中。下面存储了比萨的两方面信息:外皮类型和配料列表(是一个键'toppings'相关联的值)。
>>> # 存储所点比萨的信息
>>> pizza = {
>>> 'crust': 'thick',
>>> 'toppings': ['mushrooms', 'extra cheese'],
>>> } #存储顾客所点比萨的信息的字典
>>> # 概述所点的比萨
>>> print(f"You ordered a {pizza['crust']}-crust pizza with the following toppings:")
>>> for topping in pizza['toppings']:
>>> print("\t" + topping)
下面的输出概述了要制作的比萨:
You ordered a thick-crust pizza with the following toppings:
mushrooms
extra cheese
要在字典中将一个键关联到多个值时,可在字典中嵌套一个列表。如被调查者可喜欢多种语言,这样每个被调查者相关联的都是一个语言列表:
>>> favorite_languages = {
>>> 'jen': ['python', 'ruby'],
>>> 'sarah': ['c'],
>>> 'edward': ['ruby', 'go'],
>>> 'phil': ['python', 'haskell'],
>>> }
>>> for name, languages in favorite_languages.items():
>>> print(f"\n{name.title()}'s favorite languages are:")
>>> for language in languages:
>>> print(f"\t{language.title()}")
输出:Jen's favorite languages are:
Python
Ruby
Sarah's favorite languages are:
C
Edward's favorite languages are:
Ruby
Go
Phil's favorite languages are:
Python
Haskell
注意 列表和字典的嵌套层级不应太多。
可在字典中嵌套字典,但这样代码可能变复杂。例如,如果有多个网站用户,每个都有独特的用户名,可在字典中将用户名作为键,然后将每位用户的信息存储在一个字典中,并将该字典作为与用户名相关联的值。对于每位用户,都存储了三项信息:名、姓和居住地:
>>> users = { #定义一个名为users的字典
>>> 'aeinstein': {
>>> 'first': 'albert',
>>> 'last': 'einstein',
>>> 'location': 'princeton',
>>> },
>>> 'mcurie': {
>>> 'first': 'marie',
>>> 'last': 'curie',
>>> 'location': 'paris',
>>> },
>>> }
>>> for username, user_info in users.items():
>>> print(f"\nUsername: {username}")
>>> full_name = f"{user_info['first']} {user_info['last']}"
>>> location = user_info['location']
>>> print(f"\tFull name: {full_name.title()}")
>>> print(f"\tLocation: {location.title()}")
上面字典包含两个键:用户名'aeinstein'和'mcurie';与每个键相关联的值都是一个字典,其中包含用户的名、姓和居住地。输出:
Username: aeinstein
Full name: Albert Einstein
Location: Princeton
Username: mcurie
Full name: Marie Curie
Location: Paris
注意,表示每位用户的字典的结构最好都相同,这处理起来更容易。
在本章中学习了:
在下一章将学习while循环以及如何从用户那里获取输入。
说明:记录学习笔记,如果错误欢迎指正!写文章不易,转载请联系我。