有时候,需要将多个字典存储在一个列表中,或将一个列表作为值存储在字典中,这种技术称为嵌套。你可以在列表中嵌套字典,在字典中嵌套列表,甚至在字典中嵌套字典。正如下面的例子所示,嵌套是一个非常强大的功能。
字典列表
假设我们有一个名为 alien_0
的字典,它包含了某个外星人的各种信息。然而,如果我们想要存储多个外星人的信息,仅用一个字典是不够的。为了管理一群外星人,我们可以创建一个包含多个字典的列表,每个字典代表一个外星人及其相关信息。例如:
1
2
3
4
5
6
7
8
9
10
11
| # 创建三个表示外星人的字典
alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
# 将这些字典存储到一个名为 aliens 的列表中
aliens = [alien_0, alien_1, alien_2]
# 遍历列表并打印每个外星人的信息
for alien in aliens:
print(alien)
|
首先,我们定义了三个字典,每个字典都表示一个不同的外星人。然后,我们将这些字典添加到一个名为 aliens
的列表中,并通过循环遍历该列表,依次打印出每个外星人的信息:
1
2
3
| {'color': 'green', 'points': 5}
{'color': 'yellow', 'points': 10}
{'color': 'red', 'points': 15}
|
在实际应用中,外星人的数量可能会非常多,而且每个外星人都是通过代码自动生成的。我们可以利用 range()
函数和循环来实现这一点:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 创建一个空列表用于存储外星人
aliens = []
# 使用循环生成 30 个绿色的外星人
for alien_number in range(30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)
# 显示前 5 个外星人
for alien in aliens[:5]:
print(alien)
print("...")
# 打印总共创建了多少个外星人
print(f"Total number of aliens: {len(aliens)}")
|
在这个例子中,我们首先创建了一个空列表 aliens
。然后,通过循环生成了 30 个具有相同属性(绿色、5 分、慢速)的外星人,并将它们添加到列表中。接着,我们通过切片操作展示了列表中的前五个外星人,并打印出了列表的总长度以确认确实创建了 30 个外星人:
1
2
3
4
5
6
7
8
| {'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
|
随着游戏的发展,某些外星人可能会变色并且加快移动速度。这时,我们可以结合 if
语句来修改特定条件下的外星人属性。例如,要将前三个外星人改为黄色、中等速度且得分为 15 分,可以这样做:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 创建一个空列表用于存储外星人
aliens = []
# 创建 30 个绿色的外星人
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['speed'] = 'medium'
alien['points'] = 10
# 显示前 5 个外星人
for alien in aliens[:5]:
print(alien)
print("...")
|
这里,我们检查列表中的前三个外星人是否为绿色。如果是,则将其颜色改为黄色,速度设为中等,并增加其得分点数。输出结果如下:
1
2
3
4
5
6
| {'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 分的红色外星人:
1
2
3
4
5
6
7
8
9
| 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'
,就像访问字典中的其他值一样。这将返回一个包含所有配料的列表,而不是单个值:
1
2
3
4
5
6
7
8
9
10
11
12
| # 存储顾客所点比萨的信息
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(f"\t{topping}")
|
首先,我们创建了一个字典来存储有关顾客所点比萨的信息。在这个字典中,键 'crust'
对应的值是字符串 'thick'
,表示比萨的外皮类型;另一个键 'toppings'
对应的值是一个列表,其中包含了顾客选择的所有配料。为了概述顾客点的比萨,我们打印出比萨的外皮类型,并通过 for
循环遍历并打印出所有的配料。当需要在 print()
函数中书写较长的字符串时,可以将其分成多行书写,并确保每行都用引号括起来,且从第二行开始缩进。Python 将自动合并这些字符串。
输出结果如下:
1
2
3
| You ordered a thick-crust pizza with the following toppings:
mushrooms
extra cheese
|
每当需要在一个字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。例如,在使用字典关于喜欢编程语言的例子中,如果我们将每个人的回答存储在一个列表中,被调查者就可以选择多种喜欢的语言。在这种情况下,当我们遍历字典时,每个被调查者关联的都是一个语言列表,而不是一种语言。因此,在遍历该字典的 for
循环中,需要再使用一个 for
循环来遍历每个人喜欢的语言列表:
1
2
3
4
5
6
7
8
9
10
11
| favorite_languages = {
'jen': ['python', 'rust'],
'sarah': ['c'],
'edward': ['rust', '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()}")
|
在这个例子中,每个人的名字都对应着一个语言列表。请注意,有些人只喜欢一种语言,而有些人则喜欢多种语言。在遍历字典时,我们使用变量 languages
来依次存储字典中的每个值,因为我们知道这些值都是列表。然后,我们在主循环中再使用一个 for
循环来遍历每个人喜欢的语言列表。现在,每个人可以列出任意数量的喜欢的语言:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| Jen's favorite languages are:
Python
Rust
Sarah's favorite languages are:
C
Edward's favorite languages are:
Rust
Go
Phil's favorite languages are:
Python
Haskell
|
为了进一步改进这个程序,可以在遍历字典的 for
循环开头添加一条 if
语句,通过检查 len(languages)
的值来确定当前被调查者喜欢的语言是否有多种。如果他喜欢的语言不止一种,就按之前的格式显示输出;如果只有一种,则相应地修改输出措辞,例如显示 “Sarah’s favorite language is C”。
注意:尽量避免过多的列表和字典嵌套层级。如果嵌套层级比前面的示例复杂得多,很可能存在更简单的解决方案。
在字典中存储字典
可以在字典中嵌套字典,但这样可能会让代码变得复杂。例如,如果有一个网站有多个用户,每个用户都有独特的用户名,可以将用户名作为键,并将每个用户的信息存储在一个字典中,然后将该字典作为与用户名关联的值。下面的程序展示了如何存储每个用户的三项信息:名、姓和居住地。为了访问这些信息,我们遍历所有的用户名,并访问与每个用户名关联的信息字典:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| 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()}")
|
首先定义一个名为 users
的字典,其中包含两个键:用户名 'aeinstein'
和 'mcurie'
。与每个键关联的值都是一个字典,其中包含用户的名、姓和居住地。
然后,遍历字典 users
,Python 依次将每个键赋给变量 username
,并将与当前键相关联的字典赋给变量 user_info
。在循环内部,打印出用户名。
接下来,开始访问内部的字典。变量 user_info
包含用户信息字典,该字典包含三个键:'first'
、'last'
和 'location'
。对于每个用户,都使用这些键来生成整洁的姓名和居住地,然后打印有关用户的简要信息:
1
2
3
4
5
6
7
| Username: aeinstein
Full name: Albert Einstein
Location: Princeton
Username: mcurie
Full name: Marie Curie
Location: Paris
|
请注意,表示每个用户的字典都有相同的结构,虽然 Python 并没有这样的要求,但这使得嵌套的字典处理起来更加容易。如果表示每个用户的字典包含不同的键,那么 for
循环内部的代码将会变得更加复杂。