第六章 字典
In [1]:
# 理解字典后就能够更准确的为各种真实物体建模。
In [2]:
alien_0 = {'color':'green','points':5}
print(alien_0['color'])
print(alien_0['points'])
green
5
In [3]:
# 字典能够高效的模拟现实世界中的情形。
In [4]:
# 对每个键都与一个值相关联。
# 与键相关联的值可以是数/字符串/列表乃至字典。
# 字典用放在花括号({})中的一系列键值对表示:
# 键值对之间用逗号分隔。
In [5]:
alien_0 = {'color':'green'}
① 访问字典中的值
In [6]:
alien_0 = {'color':'green'}
print(alien_0['color'])
green
In [7]:
# 如果玩家射杀了这个外星人,就可以使用下面的代码来确定获得多少分:
In [8]:
alien_0 = {'color':'green','points':5} #注意这是{字典},,不是[列表]
new_points = alien_0['points']
print(f"You just earned {new_points} points!")
You just earned 5 points!
②添加键值对
In [9]:
# 字典是一种动态结构,可随时在其中添加键值对。
# eg.在字典alien_0中添加两项信息:
# 外星人的X坐标和Y坐标;
# 屏幕坐标系的圆点通常为左上角;
# 要将该外星人放在屏幕左边缘,可将X坐标设置为0;
# 要将该外星人放在离屏幕顶部25像素的地方,可将Y坐标设置为25。
In [10]:
alien_0 = {'color':'green', 'points':5}
print(alien_0)
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)
{'color': 'green', 'points': 5}
{'color': 'green', 'points': 5, 'x_position': 0, 'y_position': 25}
In [11]:
# 在Python3.7中,字典中元素的排列顺序与定义时相同。即打印出来或遍历其元素与添加顺序相同。
③先创建一个空字典
In [12]:
# 可先使用一对空花括号定义一个字典;
# 再分行添加各个键值对。
In [13]:
alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
print(alien_0)
{'color': 'green', 'points': 5}
④修改字典中的值
In [14]:
# eg.要修改字典中的值,假设随着游戏的进行,需要将一个外星人从绿色改为黄色。
alien_0 = {'color': 'green'}
print(f"The alien is {alien_0['color']}.")
alien_0['color'] = 'yellow'
print(f"The alien is now {alien_0['color']}.")
The alien is green.
The alien is now yellow.
In [15]:
# eg.对一个能够与不同速度移动的外星人进行位置追踪:
In [16]:
alien_0 = {'x_position':0, 'y_position':25, 'speed':'medium'}
print(f"Original x_position: {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(f"New x_position:{alien_0['x_position']}") #alien_0['x_position']:同一变量,但以修改。
Original x_position: 0.
New x_position:2
In [17]:
# 通过修改外星人字典中的值,可改变外星人的行为。
# 例如要将这个速度中等的外星人变成速度很快的外星人,可添加代码行:
alien_0['speed'] = 'fast'
# 再次运行这些代码时,其中的if-elif-else结构将把一个更大的值赋给变量x_increment。
⑤删除键值对
In [18]:
alien_0 = {'color':'green', 'points':5}
print(alien_0)
del alien_0['points']
print(alien_0)
{'color': 'green', 'points': 5}
{'color': 'green'}
⑥由类似对象组成的字典
In [20]:
# 在前面的事例中,字典存储的是一个对象(游戏中的一个外星人)的多种信息。
# 也可以使用字典来存储众多对象的同一种信息。
# eg.假设你要调查很多人,询问他们最喜欢的编程语言,可使用一个字典来存储这种简单调查的结果:
In [21]:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python,'
}
In [22]:
# 定义好字典后,在最后一个键值对的下一行添加一个右花括号,并缩进四个空格;
# 也可以在最后一个键值对最后面也加上逗号。
In [23]:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python,'
}
language = favorite_languages['sarah'].title() #为了获得Sarah喜欢的语言。
print(f"Sarah's favorite language is {language}.")
Sarah's favorite language is C.
⑦使用get()来访问值
In [24]:
# 如果指定的键不存在就会出错。
# 如果你要求获取外星人的分数,这个外星人没有分数,这将导致Python显示trackback,指出存在键值错误(KeyError):
alien_0 = {'color':'green', 'speed':'slow'}
print(alien_0['points'])
---------------------------------------------------------------------------KeyError Traceback (most recent call last)
Cell In[24], line 4 1 # 如果指定的键不存在就会出错。 2 # 如果你要求获取外星人的分数,这个外星人没有分数,这将导致Python显示trackback,指出存在键值错误(KeyError): 3 alien_0 = {'color':'green', 'speed':'slow'}----> 4 print(alien_0['points'])
KeyError: 'points'
In [25]:
# 就字典而言,可使用方法get()在指定的键不存在时返回一个默认值,从而避免这样的错误。
# get():两个参数:
In [26]:
alien_0 = {'color':'green', 'speed':'slow'}
point_value = alien_0.get('points','No point value assigned.')
print(point_value)
No point value assigned.
In [27]:
# 如果指定的键有可能不存在,应考虑使用方法get(),而不要使用方括号表示法。
# 调用get()时,如果没有指定第二个参数前指定的键不存在Python将返回值None,这个特殊值表示没有相应的值;
# None并非错误,而是一个表示所需值不存在的特殊值。
6.3 遍历字典
①遍历所有键值对。
In [28]:
user_0 = {
'username':'efermi',
'first':'enrico',
'last':'fermi',
}
for key,value in user_0.items():
print(f"\nKey:{key}")
print(f"Value:{value}")
Key:username
Value:efermi
Key:first
Value:enrico
Key:last
Value:fermi
In [29]:
for k,v in user_0.items():
print(f"\nKey:{key}") # 在每个键值对前都插入一个空行
print(f"Value:{value}")
Key:last
Value:fermi
Key:last
Value:fermi
Key:last
Value:fermi
In [30]:
# 方法items(),返回一个键值对列表。
# 由于字典中的键都是人名,值都是语言,因此在循环中使用变量name和language,而不是key和value,这让人更容易明白循环的作用:
In [31]:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python,'
}
8
for name,language in favorite_languages.items():
print(f"{name.title()}'s favorite language is {language.title()}.")
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python,.
②遍历字典中的所有键
In [32]:
# 在不需要使用字典中的值时,方法keys()很有用。
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python,'
}
for name in favorite_languages.keys():
print(name.title())
Jen
Sarah
Edward
Phil
In [33]:
# 遍历字典时,会默认遍历所有的键:
# 将 for name in favorite_languages.keys():替换为:
for name in favorite_languages:
print(name.title())
# 输出将不变。 (即与值value无关)
Jen
Sarah
Edward
Phil
In [34]:
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python,'
}
friends = ['phil', 'sarah'] #
for name in favorite_languages.keys(): #
print(f"Hi {name.title()}.")
if name in friends: #
language = favorite_languages[name].title()
print(f"\t{name.title()},I see you love{language}!")
Hi Jen.
Hi Sarah.
Sarah,I see you loveC!
Hi Edward.
Hi Phil.
Phil,I see you lovePython,!
In [35]:
# 上述解析:
# 创建了一个列表;
# 在循环中打印每个人的名字;
# 如果在,就打印一句特殊的问候语。
In [36]:
# 方法keys()确定某个人是否接受了调查:(take our poll!")
# 方法keys()并非只能用于遍历,实际上它返回一个列表。
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!
③按特定顺序遍历字典中的所有键。
In [37]:
# 使用函数sorted()来获得按特定顺序排列的键列表的副本:
In [38]:
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.")
# 上述对字典方法keys()的结果调用了函数sorted()。
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.
④遍历字典中的所有值。
In [39]:
# 方法values():
# 可返回一个值列表,不包含任何键,
# 只包含被调查者选择的各种语言,而不包含被调查者的名字:
In [40]:
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,
In [41]:
# 这种做法提取字典中所有的值,而没有考虑是否重复;
# 为剔除重复项,可使用集合(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:
C
Ruby
Python,
Python
In [42]:
# 一对花括号:可直接创建集合,
# 用逗号分隔元素:
languages = {'python', 'ruby', 'python', 'c'}
languages
Out[42]:
{'c', 'python', 'ruby'}
In [43]:
languages = {'python', 'ruby', 'python', 'c',} # vs以上:在最后一个元素后面加了逗号
languages
Out[43]:
{'c', 'python', 'ruby'}
In [44]:
# 集合和字典很容易混淆,因为他们都是一对花括号定义的;
# 当花括号内没有键值对时,定义的很可能是集合;
# 不同于列表和字典,集合不会以特定的顺序存储元素。
6.4 嵌套
In [45]:
# 嵌套:将一系列字典存储在列表中,或将列表作为值存储在字典中;
# 甚至在字典中嵌套字典。
In [46]:
# eg1.字典包含一个外星人的各种信息,但无法存储第二个外星人的信息,更别说屏幕上全部外星人的信息了,如何管理成群结队的外星人呢?:
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}
In [47]:
# eg2.更符合现实的情形是,外星人不止三个,且每个外星人都是使用代码自动生成的。
# 使用range()生成了30个外星人:
aliens = []
for alien_number in range(30):
new_alien = {'color': 'green', 'points':5, 'speed': 'slow'}
aliens.append(new_alien)
for alien in aliens[:5]: #注意冒号(for)
print(alien)
print("...")
print(f"Total number of aliens: {len(aliens)}") #是30,不是5.
{'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
In [48]:
# ①创建一个用于存储外星人的空列表。
# ②创建30个绿色外星人。
# range():返回一系列数,其唯一的用途是告诉Python要重复这个循环多少次。
# append():并将其附加到列表aliens末尾。
# ③使用切片:显示前5个外星人。
# ④显示创建了多少个外星人。
In [49]:
# 这些外星人都具有相同的特征,但在Python看来,每个外星人都是独立的,这让我们能够独立地修改每个外星人。
aliens = []
for alien_number in range(30):
new_alien = {'color': 'green', 'points':5, 'speed': 'slow'}
aliens.append(new_alien)
# 修改为黄色:
for alien in aliens[:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['color'] = 'medium'
alien['points'] = 10
for alien in aliens[:5]: # for前不能空格,in aliens记得加s
print(alien)
print('...')
{'color': 'medium', 'points': 10, 'speed': 'slow'}
{'color': 'medium', 'points': 10, 'speed': 'slow'}
{'color': 'medium', 'points': 10, 'speed': 'slow'}
{'color': 'green', 'points': 5, 'speed': 'slow'}
{'color': 'green', 'points': 5, 'speed': 'slow'}
...
In [50]:
#【tips】
# if一个变量
# []中的变量记得加‘’单引号
# 等于号=右边的值记得加‘’单引号
# if记得双等号==和冒号:
# 设置变量值记得一个等号=
In [51]:
# 可进一步扩展这个循环,修改外星人:
for alien in aliens[:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['color'] = 'medium'
alien['points'] = 10
elif alien['color'] == 'yellow':
alien['color'] = 'red'
alien['speed'] = 'fast'
alien['points'] = 15
I
n [52]:
# ①经常需要在列表中包含大量的字典,其中的每个字典都包含特定对象的众多信息;
# ②可能需要为网站的每个用户创建一个字典,并将这些字典存储在一个名为users的列表中;
# ③在这个列表中,所有字典的结构都相同:
# 因此可以遍历这个列表,并以相同的方式处理其中的每个字典。
6.4.1 在字典中存储列表
In [53]:
# 需要将列表存储在字典中。
# 描述顾客点的披萨:
# 如果使用列表,只能存储要添加的披萨配料;
# 但如果使用字典,就不仅可在其中包含配料列表,还可以包含其他有关披萨的描述:
In [54]:
# eg. 存储了披萨的两方面信息:外皮类型和配料列表:
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 pizzawith the following toppings:
mushrooms
extra cheese
In [55]:
# 【tips】
# 首先创建一个字典,存储有关顾客所点披萨的信息
#每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。
# 函数调用print()中的字符串很长,可以在合适的位置分行
# 只需要在每行末尾都加上引号
# 其他各行,都在行首加上引号并缩进。
In [56]:
favorite_languages = {
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python,'
}
for name,languges 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:
C
Ruby
Python
Sarah's favorite languages are:
C
Ruby
Python
Edward's favorite languages are:
C
Ruby
Python
Phil's favorite languages are:
C
Ruby
Python
In [57]:
# ②for:
# 遍历字典时,使用变量languages来依次存储对字典中每个值的引用:
# 这些值都是列表。
# ③for:
# 使用另一个for循环来便利每个人喜欢的语言列表,
# 现在每个人想列出多少种喜欢的语言都可以。
In [58]:
# 为进一步改进这个程序,可在遍历字典的for循环开头添加一条if语句;
# 查看len(languages)到时来确定当前的被调查者喜欢的语言是否有多种
# 如果只有一种,则相应修改输出的措辞,则显示is,
# 列表和字典的嵌套层级不应太多。
6.4.3 在字典中存储字典
In [59]:
# 可在字典中嵌套字典,但这样做时,代码可能很快复杂起来.
In [60]:
users = {
'aen':{
'first': 'alka',
'last': 'en',
'location': 'beiji',
},
'ing':{
'first': 'iea',
'last': 'ng',
'location': 'lee',
},
}
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()}")
Username: aen
Full name: Alka En
Location: Beiji
Username: ing
Full name: Iea Ng
Location: Lee
In [61]:
# [tips]
# 为了使嵌套的字典处理起来更容易,可以让表示每位用户的自带你都具有相同的结构。