理解字典后,就能够更准确地为各种真实物体建模(用来模拟现实世界中的情形)。
6.1 一个简单的字典
下面是一个简单的字典,存储了某个外星人的信息(颜色和身高):
alien_0={'color':'green','height':100}
print(alien_0['color'])
print(alien_0['height'])
6.2 使用字典
在Python中,字典是一系列键值对。每个键都与一个值相关联,你可使用键来访问相关联的值。与键相关联的值可以是数、字符串、列表乃至字典。
在Python中,字典用放在花括号({})中的一系列键值对表示。
键和值之间用冒号分隔,而键值对之间用逗号分隔。
6.2.1 访问字典中的值
要获取与键相关联的值,可依次指定字典名和放在方括号内的键。
alien_0['color']
6.2.2 添加键值对
字典是一种动态结构,可随时在其中添加键值对。要添加键值对,可依次指定字典名、用方括号括起的键和相关联的值。
alien_0={'color':'green','height':100}
print(alien_0)
alien_0['x_position']=0
alien_0['y_position']=25
print(alien_0)
6.2.3 先创建一个空字典
alien_0 = {}
使用字典来存储用户提供的数据或在编写能自动生成大量键值对的代码时,通常需要先定义一个空字典。
6.2.4 修改字典中的值
要修改字典中的值,可依次指定字典名、用方括号括起的键,以及与该键相关联的新值。
alien_0={'color':'green'}
print(alien_0)
alien_0['color']='yellow'
print(alien_0)
来看一个更有趣的例子,对一个能够以不同速度移动的外星人进行位置跟踪。
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'}
print(f"Original position: {alien_0['x_position']}")
# Move the alien to the right.
# Determine how far to move the alien based on its current speed.
if alien_0['speed'] == 'slow':
x_increment = 1
elif alien_0['speed'] == 'medium':
x_increment = 2
else:
# This must be a fast alien.
x_increment = 3
# The new position is the old position plus the increment.
alien_0['x_position'] = alien_0['x_position'] + x_increment
print(f"New position: {alien_0['x_position']}")
6.2.5 删除键值对
使用del语句,指定字典名和要删除的键。
alien_0={'color':'green','points':5} #points代表外星人被你击落时,你将获得的分数
print(alien_0)
del alien_0['points']
print(alien_0)
6.2.6 由类似对象组成的字典
使用字典来存储众多对象的同一种信息。
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
确定需要使用多行来定义字典时,要在输入左花括号后按回车键。在下一行缩进四个空格,指定第一个键值对,并在它后面加上一个逗号。
定义好字典后,在最后一个键值对的下一行添加一个右花括号,并缩进四个空格,使其与字典中的键对齐。一种不错的做法是,在最后一个键值对后面也加上逗号,为以后在下一行添加键值对做好准备。
6.2.7 使用get()来访问值
使用放在方括号内的键从字典中获取感兴趣的值时,可能会引发问题:如果指定的键不存在就会出错。
可以使用get()方法在指定的键不存在时返回一个默认值,从而避免这样的错误。
方法get()的第一个参数用于指定键,是必不可少的;第二个参数为指定的键不存在时要返回的值,是可选的:
alien_0={'color':'green'}
print(alien_0.get('points','5')) #5就是默认值
注意 调用get()时,如果没有指定第二个参数且指定的键不存在,Python将返回值None。这个特殊值表示没有相应的值。None并非错误,而是一个表示所需值不存在的特殊值。
动手试一试
练习6-1:人
使用一个字典来存储一个熟人的信息,包括名、姓、年龄和居住的城市。该字典应包含键first_name、last_name、age和city。将存储在该字典中的每项信息都打印出来。
练习6-2:喜欢的数
使用一个字典来存储一些人喜欢的数。请想出5个人的名字,并将这些名字用作字典中的键;找出每个人喜欢的一个数,并将这些数作为值存储在字典中。打印每个人的名字和喜欢的数。为了让这个程序更有趣,通过询问朋友确保数据是真实的。
练习6-3:词汇表
Python字典可用于模拟现实生活中的字典。为避免混淆,我们将后者称为词汇表。
▲ 想出你在前面学过的5个编程术语,将其用作词汇表中的键,并将它们的含义作为值存储在词汇表中。
▲ 以整洁的方式打印每个术语及其含义。为此,可先打印术语,在它后面加上一个冒号,再打印其含义;也可在一行打印术语,再使用换行符(\n)插入一个空行,然后在下一行以缩进的方式打印其含义。
6.3 遍历字典
可遍历字典的所有键值对,也可仅遍历键或值。
6.3.1 遍历所有键值对
user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for key, value in user_0.items():
print(f"\nKey: {key}")
print(f"Value: {value}")
favorite_languages.py中,字典存储的是不同人的同一种信息。对于类似这样的字典,遍历所有的键值对很合适。
6.3.2 遍历字典中的所有键
在不需要使用字典中的值时,方法keys()很有用。
遍历字典时,会默认遍历所有的键,所以不用keys()也行。
下面来打印两条消息,一条是姓名,另一条是在名字为指定朋友的名字时,指出其喜欢的语言:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
friends = ['phil', 'sarah']
for name in favorite_languages.keys():
print(name.title())
if name in friends:
language = favorite_languages[name].title()
print(f"\t{name.title()}, I see you love {language}!")
方法keys()返回一个列表,其中包含字典中的所有键。
6.3.3 按特定顺序遍历字典中的所有键
要以特定顺序返回元素,一种办法是在for循环中对返回的键进行排序。
for name in sorted(favorite_languages.keys()):
print(name)
6.3.4 遍历字典中的所有值
使用方法values()来返回一个值列表,不包含任何键。
为剔除重复项,可使用集合(set)。集合中的每个元素都必须是独一无二的:
for value in set(favorite_languages.values()):
print(value)
注意 可使用一对花括号直接创建集合,并在其中用逗号分隔元素。
集合不会以特定的顺序存储元素。
动手试一试
练习6-4:词汇表2
现在你知道了如何遍历字典,可以整理为完成练习6-3而编写的代码,将其中的一系列函数调用print()替换为一个遍历字典中键和值的循环。确定该循环正确无误后,再在词汇表中添加5个Python术语。当你再次运行这个程序时,这些新术语及其含义将自动包含在输出中。
练习6-5:河流 创建一个字典,在其中存储三条重要河流及其流经的国家。例如,一个键值对可能是'nile': 'egypt'。使用循环为每条河流打印一条消息,下面是一个例子。The Nile runs through Egypt.
▲ 使用循环将该字典中每条河流的名字打印出来。
▲ 使用循环将该字典包含的每个国家的名字打印出来。
练习6-6:调查
在6.3.1节编写的程序favorite_languages.py中执行以下操作。
▲ 创建一个应该会接受调查的人员名单,其中有些人已包含在字典中,而其他人未包含在字典中。
▲ 遍历这个人员名单。对于已参与调查的人,打印一条消息表示感谢;对于还未参与调查的人,打印一条消息邀请他参加。
6.4 嵌套
有时候,需要将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套。
6.4.1 字典列表
列表存储字典类型的数据。
alien_0 = {'color': 'green', 'points': 5, 'speed': 'slow'}
alien_1 = {'color': 'yellow', 'points': 5, 'speed': 'slow'}
alien_2 = {'color': 'blue', 'points': 5, 'speed': 'slow'}
aliens = [alien_0,alien_1,alien_2]
for alien in aliens:
print(alien)
在下面的示例中,使用range()生成了30个外星人:
# Make an empty list for storing aliens.
aliens = []
# Make 30 green aliens.
for alien_number in range(30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)
# Show the first 5 aliens.
for alien in aliens[:5]:
print(alien)
print("...")
这些外星人都具有相同的特征,但在Python看来,每个外星人都是独立的,这让我们能够独立地修改每个外星人:
for alien in aliens[:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['speed'] = 'medium'
alien['points'] = 10
6.4.2 在字典中存储列表
通过列表做为值,存储到字典中。
每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。
# Store information about a pizza being ordered.
pizza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}
# Summarize the order.
print(f"You ordered a {pizza['crust']}-crust pizza "
"with the following toppings:")
for topping in pizza['toppings']:
print("\t" + topping)
上述代码中,第一个print()中的字符串很长,我们在合适的位置分了行,但运行结果还是一行。为达到这个目的,只需要在每行末尾都加上引号,同时对于除第一行外的其他各行,都在行首加上引号并缩进。这样,Python将自动合并圆括号内的所有字符串。
前面的例子中,假如喜欢的语言有多个:
favorite_languages = {
'jen': ['python','ruby','java'],
'sarah': ['c'],
'edward': ['ruby','c'],
'phil': ['python','php']
}
for name,languages in favorite_languages.items():
print(f"{name.title()}'s favorite_languages are:")
for language in languages:
print(f"\t{language.title()}")
有的人喜欢的语言只有一种,那应该输出类似这样的,“孙悟空喜欢的语言是python”:
favorite_languages = {
'jen': ['python','ruby','java'],
'sarah': ['c'],
'edward': ['ruby','c'],
'phil': ['python','php']
}
for name,languages in favorite_languages.items():
if len(languages) == 1:
print(f"{name.title()}'s favorite_language is {languages[0].title()}" )
elif len(languages) > 1:
print(f"{name.title()}'s favorite_languages are:")
for language in languages:
print(f"\t{language.title()}")
注意 列表和字典的嵌套层级不应太多。如果嵌套层级比前面的示例多得多,很可能有更简单的解决方案。
6.4.3 在字典中存储字典
在下面的程序中,存储了每位用户的三项信息:名、姓和居住地:
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()}")
请注意,表示每位用户的字典都具有相同的结构。虽然Python并没有这样的要求,但这使得嵌套的字典处理起来更容易。
动手试一试
练习6-7:人们
在为完成练习6-1而编写的程序中,再创建两个表示人的字典,然后将这三个字典都存储在一个名为people的列表中。遍历这个列表,将其中每个人的所有信息都打印出来。
练习6-8:宠物
创建多个表示宠物的字典,每个字典都包含宠物的类型及其主人的名字。将这些字典存储在一个名为pets的列表中,再遍历该列表,并将有关每个宠物的所有信息都打印出来。
练习6-9:喜欢的地方
创建一个名为favorite_places的字典。在这个字典中,将三个人的名字用作键,并存储每个人喜欢的1~3个地方。为了让这个练习更有趣些,可以让一些朋友说出他们喜欢的几个地方。遍历这个字典,并将其中每个人的名字及其喜欢的地方打印出来。
练习6-10:喜欢的数2 修改为完成练习6-2而编写的程序,让每个人都可以有多个喜欢的数,然后将每个人的名字及其喜欢的数打印出来。
练习6-11:城市 创建一个名为cities的字典,将三个城市名用作键。对于每座城市,都创建一个字典,并在其中包含该城市所属的国家、人口约数以及一个有关该城市的事实。在表示每座城市的字典中,应包含country、population和fact等键。将每座城市的名字以及有关信息都打印出来。
练习6-12:扩展 本章的示例足够复杂,能以很多方式进行扩展。请对本章的一个示例进行扩展:添加键和值、调整程序要解决的问题或改进输出的格式。
6.5 小结
在本章中,你学习了:如何定义字典,以及如何使用存储在字典中的信息;如何访问和修改字典中的元素,以及如何遍历字典中的所有信息;如何遍历字典中所有的键值对、所有的键和所有的值;如何在列表中嵌套字典、在字典中嵌套列表以及在字典中嵌套字典。