乐趣区

关于python:Python-111Python手把手教程之字典的用法和对字典的管理

作者 | 弗拉德
起源 | 弗拉德(公众号:fulade_me)

字典

字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值 key=>value对用冒号 : 宰割,每个键值对之间用逗号 , 宰割,整个字典包含在花括号 {} 中。

应用字典

在 Python 中,字典是一系列 键—值 对。每个键都与一个值相关联,你能够应用键来拜访与之相关联的值。与键相关联的值能够是数字、字符串、列表乃至字典。事实上,可将任何 Python 对象用作字典中的值。
来看一个游戏,其中蕴含一些外星人,这些外星人的色彩和点数各不相同,如下所示:

alien_0 = {'color': 'green', 'points': 5}

键—值对是两个相关联的值。指定键时,Python 将返回与之相关联的值。键和值之间用冒号分隔,而键—值对之间用逗号分隔。在字典中,你想存储多少个键—值对都能够。
最简略的字典只有一个键—值对,如下述批改后的字典 alien_0 所示:

alien_0 = {'color': 'green'}

这个字典只存储了一项无关 alien_0 的信息,具体地说是这个外星人的色彩。在这个字典中,字符串 color 是一个键,与之相关联的值为green

拜访字典中的值

要获取与键相关联的值,可顺次指定字典名和放在方括号内的键,如下所示:

alien_0 = {'color': 'green'}
print(alien_0['color'])

这将返回字典 alien_0 中与键 color 相关联的值:

green

字典中可蕴含任意数量的键—值对。例如,上面是最后的字典 alien_0,其中蕴含两个键— 值对:

alien_0 = {'color': 'green', 'points': 5}

当初,你能够拜访外星人 alien_0 的色彩和点数。如果玩家射杀了这个外星人,你就能够应用上面的代码来确定玩家应取得多少个点:

alien_0 = {'color': 'green', 'points': 5}
new_points = alien_0['points']
print("You just earned" + str(new_points) + "points!")

上述代码首先定义了一个字典,而后从这个字典中获取与键 points 相关联的值,并将这个值存储在变量 new_points 中。接下来,将这个整数转换为字符串,并打印一条音讯,指出玩家取得了多少个点:

You just earned 5 points!

增加键—值对

字典是一种动静构造,可随时在其中增加键—值对。要增加键—值对,可顺次指定字典名、用方括号括起的键和相关联的值。
上面在字典 alien_0 中增加两项信息:

外星人的 x 坐标和 y 坐标,让咱们可能在屏幕的特定地位显示该外星人。咱们将这个外星人放在屏幕左边缘,且离屏幕上边缘 25 像素的中央。因为屏幕坐标系的原点通常为左上角,因而要将该外星人放在屏幕左边缘,可将 x 坐标设置为 0,要将该外星人放在离屏幕顶部 25 像素的中央,可将 y 坐标设置为 25,如下所示:

alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
alien_0['x_position'] = 0 
alien_0['y_position'] = 25
print(alien_0)

咱们首先定义了后面始终在应用的字典,而后打印这个字典,以显示其信息快照。咱们在这个字典中新增了一个键—值对,其中的键为x_position,而值为 0。接着咱们反复这样的操作,但应用的键为y_position。打印批改后的字典时,将看到这两个新增的键—值对:

{'color': 'green', 'points': 5}
{'color': 'green', 'points': 5, 'y_position': 25, 'x_position': 0}

这个字典的最终版本蕴含四个键—值对,其中原来的两个指定外星人的色彩和点数,而新增的两个指定地位。留神,键—值对的排列程序与增加程序不同。Python 不关怀键—值对的增加程序,而只关怀键和值之间的关联关系。

创立空字典

有时候,在空字典中增加键—值对是为了不便,而有时候必须这样做。为此,可先应用一对空的花括号定义一个字典,再分行增加各个键—值对。例如,下例演示了如何以这种形式创立字典alien_0:

alien_0 = {}
alien_0['color'] = 'green' 
alien_0['points'] = 5
print(alien_0)

这里首先定义了空字典alien_0,再在其中增加色彩和点数,失去前述示例始终在应用的字典:

{'color': 'green', 'points': 5}

应用字典来存储用户提供的数据或在编写能主动生成大量键—值对的代码时,通常都须要先定义一个空字典。

批改字典中的值

要批改字典中的值,可顺次指定字典名、用方括号括起的键以及与该键相关联的新值。
例如,假如随着游戏的进行,须要将一个外星人从绿色改为黄色:

alien_0 = {'color': 'green'}
print("The alien is" + alien_0['color'] + ".")
alien_0['color'] = 'yellow'
print("The alien is now" + alien_0['color'] + ".")

咱们首先定义了一个示意外星人 alien_0 的字典,其中只蕴含这个外星人的色彩。接下来,咱们将与键 color 相关联的值改为yellow。输入表明,这个外星人的确从绿色变成了黄色:

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']))

咱们首先定义了一个外星人,其中蕴含初始的 x 坐标和 y 坐标,还有速度 medium。出于简化思考,咱们省略了色彩和点数,但即使蕴含这些键值对,这个示例的工作原理也不会有任何变动。咱们还打印了x_position 的初始值,这让用户晓得这个外星人向右挪动了多远。
而后,应用了一个 if-elif-else 构造来确定外星人应向右挪动多远,并将这个值存储在变量 x_increment 中。如果外星人的速度为 slow,它将向右挪动一个单位,如果速度为medium,将向右挪动两个单位,如果为fast,将向右挪动三个单位。确定挪动量后,将其与x_position 的以后值相加,再将后果关联到字典中的键 x_position
因为这是一个速度中等的外星人,因而其地位将向右挪动两个单位:

Original x-position: 0
New x-position: 2

通过批改外星人字典中的值,可扭转外星人的行为。例如,要将这个速度中等的外星人变成速度很快的外星人,可增加如下代码行:

alien_0['speed'] = fast 

这样,再次运行这些代码时,其中的 if-elif-else 构造将把一个更大的值赋给变量
x_increment

删除键—值对

对于字典中不再须要的信息,可应用 del 语句将相应的键—值对彻底删除。应用 del 语句时,必须指定字典名和要删除的键。
例如,上面的代码从字典 alien_0 中删除键 points 及其值:

alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
del alien_0['points'] 
print(alien_0)

上述代码将键 points 从字典 alien_0 中删除,同时删除与这个键相关联的值。输入表明,键 points 及其值 5 已从字典中删除,但其余键—值对不受影响:

{'color': 'green', 'points': 5}
{'color': 'green'}

遍历字典

一个 Python 字典可能只蕴含几个键—值对,也可能蕴含数百万个键—值对。鉴于字典可能蕴含大量的数据,Python 反对对字典遍历。字典可用于以各种形式存储信息,因而有多种遍历字典的形式,可遍历字典的所有键—值对、键或值。

遍历所有的键—值对

摸索各种遍历办法前,先来看一个新字典,它用于存储无关网站用户的信息。上面的字典存储一名用户的用户名、名和姓:

user_0 = {
    'username': 
    'efermi', 
    'first': 
    'enrico', 
    'last': 
    'fermi',
}

咱们能够应用一个 for 循环来遍历这个字典:

for key, value in user_0.items(): 
    print("\nKey:" + key)
    print("Value:" + value)

要实现遍历字典的 for 循环,可申明两个变量,用于存储键—值对中的键和值。对于这两个变量,可应用任何名称。上面的代码应用了简略的变量名,这齐全可行:

for k, v in user_0.items()

for 语句的第二局部蕴含字典名和办法 items(),它返回一个键—值对列表。接下来,for 循环顺次将每个键—值对存储到指定的两个变量中。咱们应用这两个变量来打印每个键及其相关联的值。第一条print 语句中的 ”\n” 确保在输入每个键—值对前都插入一个空行:

Key: last 
Value: fermi

Key: first 
Value: enrico

Key: username 
Value: efermi

即使遍历字典时,键—值对的返回程序也与存储程序不同。Python 不关怀键—值对的存储程序,而只跟踪键和值之间的关联关系。

遍历字典中的所有键

在不须要应用字典中的值时,办法 keys()很有用。上面来遍历字典favorite_languages,并将每个被调查者的名字都打印进去:

favorite_languages = {'jen': 'python',
                     'sarah': 'c', 
                     'edward': 'ruby', 
                     'phil': 'python'}
for name in favorite_languages.keys(): 
    print(name.title())

.keys()办法提取字典 favorite_languages 中的所有键,并顺次将它们存储到变量 name 中。输入列出了每个被调查者的名字:

Jen 
Sarah 
Phil 
Edward

遍历字典时,会默认遍历所有的键,因而,如果将上述代码中的 for name in favorite_ languages.keys(): 替换为 for name in favorite_languages:,输入将不变。如果显式地应用办法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:
        print("Hi" + name.title() + ", I see your favorite language is" + favorite_languages[name].title() + "!")

咱们创立了一个列表,其中蕴含咱们要通过打印消息,指出其喜爱的语言的敌人。在循环中,咱们打印每个人的名字,并查看以后的名字是否在列表 friends 中
如果在列表中,就打印一句非凡的问候语,其中蕴含这位敌人喜爱的语言。为拜访喜爱的语言,咱们应用了字典名,并将变量 name 的以后值作为键。每个人的名字都会被打印,但只对敌人打印非凡音讯:

Jen
Sarah
 Hi Sarah, I see your favorite language is C!
Edward
Phil
 Hi Phil, I see your favorite language is Python!

按程序遍历字典中的所有键

字典总是明确地记录键和值之间的关联关系,但获取字典的元素时,获取程序是不可预测的。
要以特定的程序返回元素,一种方法是在 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.")

这个示例中,对办法 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(),它返回一个值列表,而不蕴含任何键。
例如,如果咱们想取得一个这样的列表,即其中只蕴含被调查者抉择的各种语言,而不蕴含被调查者的名字,能够这样做:

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())

这条 for 语句提取字典中的每个值,并将它们顺次存储到变量 language 中。通过打印这些值,就取得了一个列表,其中蕴含被调查者抉择的各种语言:

The following languages have been mentioned: 
Python
C
Python
Ruby

这种做法提取字典中所有的值,而没有思考是否反复。波及的值很少时,这兴许不是问题,但如果被调查者很多,最终的列表可能蕴含大量的反复项。为剔除反复项,咱们可应用汇合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())

通过对蕴含反复元素的列表调用 set(),能够帮咱们找出列表中举世无双的元素,并应用这些元素来创立一个汇合。咱们应用了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)

咱们首先创立了三个字典,其中每个字典都示意一个外星人。咱们将这些字典都放到一个名为 aliens 的列表中。最初,咱们遍历这个列表,并将每个外星人都打印进去:

{'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("Total number of aliens:" + str(len(aliens)))

在这个示例中,首先创立了一个空列表,用于存储接下来将创立的所有外星人。range()返回一系列数字,其用处是通知 Python 咱们要反复这个循环多少次。每次执行这个循环时,都创立一个外星人,并将其附加到列表 aliens 开端。而后应用一个切片来打印前五个外星人,而后打印列表的长度,以证实的确创立了 30 个外星人

{'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 个点,能够这样做:

# 创立一个用于存储外星人的空列表 
aliens = []
# 创立 30 个绿色的外星人
for alien_number in range (0,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) 

因为咱们要批改前三个外星人,须要遍历一个只蕴含这些外星人的切片。以后,所有外星人都是绿色的,但状况并非总是如此,因而咱们编写了一条 if 语句来确保只批改绿色外星人。如果外星人是绿色的,咱们就将其色彩改为yellow,将其速度改为medium,并将其点数改为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 相关联的值。要拜访该列表,咱们应用字典名和键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)

咱们首先创立了一个字典,其中存储了无关顾客所点比萨的信息。在这个字典中,一个键是crust,与之相关联的值是字符串thick,下一个键是toppings,与之相关联的值是一个列表,其中存储了顾客要求增加的所有配料。制作前咱们概述了顾客所点的比萨。为打印配料,咱们编写了一个 for 循环。为拜访配料列表,咱们应用了键toppings,这样 Python 将从字典中提取配料列表。
上面的输入概述了要制作的比萨:

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 favorite languages are:")
    for language in languages: 
        print("\t" + language.title())

当初与每个名字相关联的值都是一个列表。请留神,有些人喜爱的语言只有一种,而有些人有多种。遍历字典时,咱们应用了变量 languages 来顺次存储字典中的每个值,因为咱们晓得这些值都是列表。在遍历字典的主循环中,咱们又应用了一个 for 循环来遍历每个人喜爱的语言列表。当初,每个人想列出多少种喜爱的语言都能够:

Jen's favorite languages are:
    Python
    Ruby
Sarah's favorite languages are:
    C
Phil's favorite languages are:
    Python
    Haskell
Edward's favorite languages are:
    Ruby
    Go

在字典中存储字典

可在字典中嵌套字典,但这样做时,代码可能很快简单起来。例如,如果有多个网站用户,每个都有独特的用户名,可在字典中将用户名作为键,而后将每位用户的信息存储在一个字典中,并将该字典作为与用户名相关联的值。
在上面的程序中,对于每位用户,咱们都存储了其三项信息: 名、姓和居住地,为拜访这些信息,咱们遍历所有的用户名,并拜访与每个用户名相关联的信息字典:

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())

咱们首先定义了一个名为 users 的字典,其中蕴含两个键: 用户名 aeinsteinmcurie,与每个键相关联的值都是一个字典,其中蕴含用户的名、姓和居住地。咱们先遍历字典 users,让 Python 顺次将每个键存储在变量username 中,并顺次将与以后键相关联的字典存储在变量 user_info 中。
在主循环外部,咱们将用户名打印进去。接着咱们开始拜访外部的字典。变量 user_info 蕴含用户信息字典,而该字典蕴含三个键:firstlastlocation,对于每位用户,咱们都应用这些键来生成整洁的姓名和居住地,而后打印无关用户的简要信息:

Username: aeinstein
Full name: Albert Einstein Location: Princeton
Username: mcurie
Full name: Marie Curie Location: Paris

小作业
11-1 请想出 5 集体的名字,并将这些名字用作字典中的键,想出每个人喜爱的一个数字,并将这些数字作为值存储在字典中。打印每个人的名字和喜爱的数字。
11-2 创立一个字典,在其中存储三条大河流及其流经的国家。其中一个键—值对可能是 ’nile’:’egypt’。应用循环为每条河流打印一条音讯,如 ”The Nile runs through Egypt.”。应用循环将该字典中每条河流的名字都打印进去。应用循环将该字典蕴含的每个国家的名字都打印进去。
11-3 创立多个字典,对于每个字典,都应用一个宠物的名称来给它命名; 在每个字典中,蕴含宠物的类型及其客人的名字。将这些字典存储在一个名为 pets 的列表中,再遍历该列表,并将宠物的所有信息都打印进去。

想查看作业答案能够去我的 Githu 仓库在文件夹(11-1——11-3)


退出移动版