接前面的文章:
Python基础入门知识(1)
Python基础入门知识(2)
Python基础入门知识(3)
2 Python的基础知识
2.15 字典
字典是一个无序、可变和有索引的集合。在 Python 中,字典用花括号({})编写,拥有键和值。
字典的格式:变量名 = {键:值}
2.15.1 一个简单的字典
来看一个游戏,其中包含一些外星人,这些外星人的颜色和点数各不相同。下面是一个简单的字典,存储了有关特定外星人的信息:
alien_0 = {'color':'green','points':5}
print(alien_0['color'])
print(alien_0['points'])
输出:
green
5
一般字典里面会有很多组信息,为了阅读更清晰,我们可以这样写:
alien_0 = {
'color':'green',
'points':5
}
2.15.2 使用字典
在Python中,每个键都与一个值相关联,我们可以使用键来访问与之相关联的值。与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可将任何Python对象用作字典中的值。
键和值之间用冒号分隔,而键—值对之间用逗号分隔。
最简单的字典只有一个键—值对,例如,我们修改上面的代码alien_0:
alien_0 = {‘color’:‘green’}
在这个字典中,字符串’color’是一个键,与之相关联的值为’green’。
2.15.3 访问字典中的值
如果要获取与键相关联的值,可依次指定字典名和放在方括号内的键,如下:
alien_0 = {'color': 'green'}
print(alien_0['color'])
2.15.4 添加键—值对
字典是一种动态结构,可随时在其中添加键—值对。要添加键—值对,可依次指定字典名、用方括号括起的键和相关联的值。
下面在字典alien_0中添加两项信息:外星人的x坐标和y坐标,让我们能够在屏幕的特定位置显示该外星人。我们将这个外星人放在屏幕左边缘,且离屏幕上边缘25像素的地方。由于屏幕坐标系的原点通常为左上角,因此要将该外星人放在屏幕左边缘,可将x坐标设置为0;要将该外星人放在离屏幕顶部25像素的地方,可将y坐标设置为25,如下所示:
alien_0 = {'color':'green','points':5} # 定义了字典
print(alien_0) # 打印这个字典,以显示其信息快照
alien_0['x_position'] = 0 # 新增了一个键—值对,其中的键为'x_position',而值为0
alien_0['y_position'] = 25# 又新增了一个键—值对,其中的键为'y_position',而值为25
print(alien_0)
输出:
{‘color’: ‘green’, ‘points’: 5}
{‘color’: ‘green’, ‘points’: 5, ‘x_position’: 0, ‘y_position’: 25}
2.15.5 先创建一个空字典
有时候,在空字典中添加键—值对是为了方便,而有时候必须这样做。为此,可先使用一对空的花括号定义一个字典,再分行添加各个键—值对。
例如:
alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
print(alien_0)
输出:
{‘color’: ‘green’, ‘points’: 5}
在实际开发中,使用字典来存储用户提供的数据或在编写能自动生成大量键—值对的代码时,通常都需要先定义一个空字典。
2.15.6 修改字典中的值
要修改字典中的值,可依次指定字典名、用方括号括起的键以及与该键相关联的新值。
例如,假设随着游戏的进行,需要将一个外星人从绿色改为黄色:
alien_0 = {'color':'green'}
print("The alien is "+alien_0['color']+".")
alien_0['color'] = 'yellow'
print("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("Original x-position: "+str(alien_0['x_position']))
# 向右移动外星人
# 据外星人当前速度决定将其移动多远
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("New x-position: "+str(alien_0['x_position']))
输出:
Original x-position: 0
New x-position: 2
我们在if-elif-else语句中定义:如果外星人的速度为’slow’,它将向右移动一个单位;如果速度为’medium’,将向右移
动两个单位;如果为’fast’,将向右移动三个单位。
由于这是一个速度中等的外星人,因此其位置将向右移动两个单位。
2.15.7 删除键—值对
对于字典中不再需要的信息,可使用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’}
需要注意的是:删除的键—值对永远消失了。
2.15.8 由类似对象组成的字典
在前面的示例中,字典存储的是一个对象(游戏中的一个外星人)的多种信息,但我们也可以使用字典来存储众多对象的同一种信息。
例如,假设我们要调查很多人,询问他们最喜欢的编程语言,可使用一个字典来存储这种简单调查的结果,如下所示:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python'
}
给定被调查者的名字,可使用这个字典轻松地获悉他喜欢的语言,例如,我们要获悉Sarah喜欢的语言:
print("Sarah's favorite language is "+favorite_languages['sarah'].title()+".")
输出:
Sarah’s favorite language is C.
2.16 遍历字典
字典可用于以各种方式存储信息,因此有多种遍历字典的方式:可遍历字典的所有键—值对、键或值。
2.16.1 遍历所有的键—值对
我们重新定义一个新字典,它用于存储有关网站用户的信息。
下面的字典存储了一名用户的用户名、名和姓:
user_0 = {
'username':'efermi',
'first':'enrico',
'last':'fermi'
}
我们可以访问user_0中的任何一项信息,但如果要获悉该用户字典中的所有信息,该怎么办呢?可以使用一个for循环来遍历这个字典:
for key,value in user_0.items():
print("\nKey: "+key)
print("Value: "+value)
输出:
Key: username
Value: efermi
Key: first
Value: enrico
Key: last
Value: fermi
2.16.2 遍历字典中的所有键
在不需要使用字典中的值时,方法keys()很有用。
下面来遍历字典favorite_languages,并将每个被调查者的名字都打印出来:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python'
}
for name in favorite_languages.keys():
print(name.title())
输出:
Jen
Sarah
Edward
Phil
下面来打印两条消息,指出两位朋友喜欢的语言。我们像前面一样遍历字典中的名字,但在名字为指定朋友的名字时,打印一条消息,指出其喜欢的语言:
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:
print(" Hi "+name.title()+
", I see your favorite language is "+
favorite_languages[name].title()+"!"
)
输出:
Jen
Sarah
Hi Sarah, I see your favorite language is C!
Edward
Phil
Hi Phil, I see your favorite language is Python!
你还可以使用keys()确定某个人是否接受了调查。下面的代码确定Erin是否接受了调查:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python'
}
if 'erin' not in favorite_languages.keys():
print("Erin, please take our poll!")
输出:
Erin, please take our poll!
2.16.3 按顺序遍历字典中的所有键
字典总是明确地记录键和值之间的关联关系,但获取字典的元素时,获取顺序是不可预测的。
如果我们要以特定的顺序返回元素,可以在for循环中对返回的键进行排序。因此,我们可以使用函数sorted()来获得按特定顺序排列的键列表的副本:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python'
}
for name in sorted(favorite_languages.keys()):
print(name.title()+", thank you for taking the poll.")
输出:
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.
2.16.4 遍历字典中的所有值
如果我们只想要字典中包含的值,可使用方法values(),它返回一个值列表,而不包含任何键。
例如,如果我们想获得一个这样的列表,即其中只包含被调查者选择的各种语言,而不包含被调查者的名字,可以这样做:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python'
}
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)。集合类似于列表,但每个元素都必须是独一无二的:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python'
}
print("The following languages have been mentioned:")
for language in set(favorite_languages.values()):
print(language.title())
输出:
The following languages have been mentioned:
Python
Ruby
C
2.17 嵌套
有时,我们需要将一系列字典存储在列表中,或将列表作为值存储在字典中,这样的行为就被称为嵌套。我们可以在列表中嵌套字典、在字典中嵌套列表甚至在字典中嵌套字典。
2.17.1 字典列表
还记得吗?上面我们有一个外星人游戏的例子。字典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("Total number of aliens: "+str(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看来,每个外星人都是独立的,这让我们能够独立地修改每个外星人。
例如,我们要将前三个外星人修改为黄色的、速度为中等且值10个点,可以这样做:
# 创建一个用于存储外星人的空列表
aliens = []
# 创建30个绿色的外星人
for alien_number in range(30):
new_alien = {'color':'green','points':5,'speed':'slow'}
aliens.append(new_alien)
for alien in aliens[0:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['speed'] = 'medium'
alien['points'] = 10
# 显示前五个外星人
for alien in aliens[0:5]:
print(alien)
print("...")
输出:
{‘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
2.17.2 在字典中存储列表
有时候,需要将列表存储在字典中,而不是将字典存储在列表中。例如,你如何描述顾客点的比萨呢?如果使用列表,只能存储要添加的比萨配料;但如果使用字典,就不仅可在其中包含配料列表,还可包含其他有关比萨的描述。
我们看一下下面的例子,案例中存储了比萨的两方面信息:外皮类型和配料列表。其中的配料列表是一个与键’toppings’相关联的值。要访问该列表,我们使用字典名和键’toppings’,就像访问字典中的其他值一样。这将返回一个配料列表,而不是单个值:
# 存储所点披萨的信息
pizza = {
'crust': 'thick',
'toppings':['mushrooms','extra cheese'],
}
# 概述所点的披萨
print("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
每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。
例如,我们前面用到的有关喜欢的编程语言的示例中,如果将每个人的回答都存储在一个列表中,被调查者就可选择多种喜欢的语言。在这种情况下,当我们遍历字典时,与每个被调查者相关联的都是一个语言列表,而不是一种语言;因此,在遍历该字典的for循环中,我们需要再使用一个for循环来遍历与被调查者相关联的语言列表:
favorite_languages = {
'jen':['python','ruby'],
'sarah':['c'],
'edward':['ruby','go'],
'phil':['python','haskell']
}
for name,languages in favorite_languages.items():
print("\n"+name.title()+"'s favortie languages are:")
for language in languages:
print("\t"+language.title())
输出:
Jen’s favortie languages are:
Python
Ruby
Sarah’s favortie languages are:
C
Edward’s favortie languages are:
Ruby
Go
Phil’s favortie languages are:
Python
Haskell
2.17.3 在字典中存储字典
字典中也可嵌套字典,但这样做时,代码可能很快复杂起来。
例如,如果有多个网站用户,每个都有独特的用户名,可在字典中将用户名作为键,然后将每位用户的信息存储在一个字典中,并将该字典作为与用户名相关联的值。在下面的程序中,对于每位用户,我们都存储了其三项信息:名、姓和居住地;为访问这些信息,我们遍历所有的用户名,并访问与每个用户名相关联的信息字典:
users = {
'aeinstein':{
'first':'albert',
'last':'einstein',
'location':'princeton'
},
'mcurie':{
'first':'marie',
'last':'curie',
'location':'paris'
}
}
for username, user_info in users.items():
print("\nUsername:"+username)
full_name = user_info['first']+" "+user_info['last']
location = user_info['location']
print("\tFull name: "+full_name.title())
print("\tLocation: "+location.title())
输出:
Username:aeinstein
Full name: Albert Einstein
Location: Princeton
Username:mcurie
Full name: Marie Curie
Location: Paris