第五章、字典
在本章中,你将学习能够将相关信息关联起来的 Python 字典。你将学习如何访问和修改字典中的信息。鉴于字典可存储的信息量几乎不受限制,因此我们会演示如何遍历字典中的数据。另外,你还将学习存储字典的列表、存储列表的字典和存储字典的字典。
理解字典后,你就能够更准确地为各种真实物体建模。你可以创建一个表示人的字典,然后想在其中存储多少信息就存储多少信息;姓名、年龄、地址、职业以及要描述的任何方面。你还能够存储任意两种相关的信息,如一系列单词及其含义,一系列人名及其喜欢的数字,以及一系列山脉及其海拔等。
5.1 一个简单的字典
dictionary = {'color': 'green', "points": 5}
从上面的例子中可以看到,字典和列表其实有点相似之处,字典存储的是一个键值对形式的数据。和 java 中的 map 差不多,不过 Python 中不用定义键值对的类型,所以在同一个字典中可以存储的键值对类型可以不一致。
5.2 使用字典
在 Python 中,字典是一系列键值对。,每个键都与一个值相关联,你可以使用键来访问与之相关联的值。与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可以将任何 Python 对象用作字典中的值。
在 Python 中,字典用放在花括号 {} 中的一系列键值对表示。键值对是两个相关联的信息。指定键时,Python 将返回与之相关联的值。键和值之间用冒号分隔。在字典中,你想存储多少个键值对都是可以的。
5.2.1 访问字典中的值
要获取与键相关联的值,可一次指定字典名和放在方括号内的键。
dictionary = {'color': 'green', 'points': 5}
print(dictionary['color'])
print(distionary['points'])
5.2.2 添加一键值对
字典是一种动态结构。可随时在其中添加键值对。要添加键值对,可依次指定字典名、用方括号起的键和相关联的值。
dictionary = {'color': 'green', 'points': 5}
print(dictionary)
dictionary['x_postition'] = 0
dictionary['y_postition'] = 15
print(dictionary)
注意:键值对的排列顺序与添加顺序不同。Python 不关心键值对的添加顺序,而知关心键和值之间的关联关系。
5.2.3 创建一个空字典
有时候,在空字典中添加键值对是为了方便,而有时候必须这样做。为此,可先使用一对空的花括号定义一个字典,再分行添加各个键值对。
dictionary = {}
dictionary['color'] = 'green'
dictionary['points'] = 10
print(dictionary)
使用字典来存储用户提供的数据或在编写能自动生成大量键值对的代码时,通常都需要先定义一个空字典。
5.2.4 修改字典中的值
要修改字典中的值,可以依次指定字典名、用方括号括起的键以及与该键相关联的新值。
dictionary = {'color': 'green'}
print(dictionary['color'])
dictionary['color'] = 'yellow'
print(dictionary['color'])
5.2.5 删除一个键值对
对于字典中不再需要的信息,可使用 del 语句将相应的键值对彻底删除。使用 del 语句时,必须指定字典名和要删除的键
dictionary = {'color': 'green', 'points': 5}
print(dictionary)
del dictionary['color']
print(dictionary)
5.2.6 由类似对象组成的字典
在前面的示例中,字典存储的是一个对象的多种信息,但你也可以使用字典来存储众多对象的同一种信息。假如:你要调查很多人,询问他们最喜欢的编程语言,可以使用一个字典来存储这种简单调查的结果
favorite_languages = {
'jen': 'python',
"kings": 'java',
'elong': 'java',
'phl': 'php',
}
正如你看到的,我们将一个较大的字典放在了多行中。其中每个键都是一个被调查者的名字,而每个值都是被调查者喜欢的语言。确定需要使用多行来定义字典时,在出入左花括号后按回车键,再在下一行缩进四个空格,指定第一个键值对,并在它后面加上一个逗号。此后你再次按回车键时,文本编辑器将自动缩进后续的键值对,且缩进量与第一个键值对相同
定义好字典后,在最后一个键值对的下一行添加一个右花括号,并缩进四个空格,使其与字典中的键对齐。另外一种不错的做法是在最后一个键值对后面也加上逗号,为以后在下一行添加键值对做好准备
注意:对于较长的列表和字典,大多数编辑器都有以类似方式设置其格式的功能。对于较长的字典,还有其他一些可行的格式设置方式,因此在你的编辑器或者其他源代码中,你可能会看到稍微不用的格式设置方式。
5.3 遍历字典
一个 Python 字典可能只包含几个键值对,也可能包含数百万个键值对。鉴于字典可能包含大量的数据,Python 支持对字典遍历。字典可用于以各种方式存储信息。因此有多中遍历字典的方式;可遍历字典的所有键值对、键或值。
5.3.1 遍历所有的键值对
可以使用一个 for 循环来遍历字典。要编写用于遍历字典的 for 循环,可以声明两个变量,用于存储键值对中的键和值。对于这两个变量,可使用任何名称。
for k,v in dictionary.items()
for 语句的第二部分包含字典名和方法 items()方法。它返回一个键值对列表。接下来,for 循环依次将每个键值对存储到指定的两个变量中。
users = {
'username': 'kings',
'first': 'king',
'last': 'fermil',
}
for key, value in users.items():
print("\nkey: " + key)
print("value: " + value)
注意:即便遍历字典时,键值对的返回顺序也与存储顺序不同。Python 不关心键值对的存储顺序,而只跟中键和值之间的关联关系。
5.3.2 遍历字典中的所有键
在不需要使用字典中的值时,方法 keys() 很有用。不过在这里需要注意:遍历字典时,会默认遍历所有的键。也就是说 for name in dictionatry.keys(): 和 for name in dictionary: 输出将不变。
users = {
'username': 'kings',
'first': 'king',
'last': 'fermil',
}
for name in users.keys():
print(name)
for name in users:
print(name)
如上所示。如果显式的使用方法 keys() 可以让代码更容易理解,你可以选择这样做,但如果你愿意,也可以省略它。
当然,keys() 方法的用法不仅如此。它返回一个列表,其中包含字典中的所有键,因此你可以使用它来判断某个元素是否包含在该列表中。如:
favorite_languages = {
'jen': 'python',
"kings": 'java',
'elong': 'java',
'phl': 'php',
}
if 'elong' not in favorite_languages.keys():
print("elong, please take our poll!")
5.3.3 按顺序遍历字典中的所有键
字典总是明确的记录键和值之间的关联关系,但获取字典的元素时,获取顺序是不可预测的。这不是问题,因为通常你想要的只是获取与键相关联的正确的值。要以特定的顺序返回元素,一种方法是在 for 循环中返回的键进行排序。为此,可使用函数 sorted() 来获得按特定顺序排列的列表的副本。
favorite_languages = {
'jen': 'python',
"kings": 'java',
'elong': 'java',
'phl': 'php',
}
for name in sorted(favorite_languages.keys()):
print(name.title() + ", thank you for taking the poll.")
这条 for 循环语句类似于其他 for 语句,但对方法 dictionary.keys() 的结果调用了函数 sorted()。折让 Python 列出字典中的所有键,并在遍历前对这个列表进行排序。
5.3.4 遍历字典中的所有值
如果你感兴趣的主要是字典中包含的值,可以使用方法 values(),它返回一个值列表,而不包含任何键。例如,如果我们想获得一个这样的列表,即其中只包含被调查者选择的各种语言,而不包含被调查者的名字。
favorite_languages = {
'jen': 'python',
"kings": 'java',
'elong': 'java',
'phl': 'php',
}
print("The following languages have been metioned:")
for language in favorite_languages.values():
print(language.title())
这条for 语句提取字典中的每个值,并将它们依次存储到变量 language 中。通过打印这些值,就获得了一个列表,其中包含被调查者选择的各种语言,这种做法提取字典中所有的值,而没有考虑是否重复。涉及的值很少时,这也许不是问题,但如果被调查者很多,最终列表中可能包含大量的重复项。为了剔除重复项,可以使用集合(Set)。集合类似于列表,但是此集合中的每个元素都是独一无二的。
favorite_languages = {
'jen': 'python',
"kings": 'java',
'elong': 'java',
'phl': 'php',
}
print("The following language have been metioned:")
for language in set(favorite_languages.values()):
print(language.title())
通过对包含重复元素的列表调用 set(),可以让 Python 找出列表中独一无二的元素,并使用这些元素来串讲一个集合。
5.4 嵌套
有时候,需要将一系列字典存储在列表中,或将列表作为值存储在点点中,这称为嵌套。你可以在列表中嵌套字典、在字典中嵌套列表甚至在字典中嵌套字典。
5.4.1 字典列表
将三个字典放到一个列表中,遍历该列表,输出列表中的每个字典。
a1 = {'color': 'green'}
a2 = {'color': 'red'}
a3 = {'color': 'yellow'}
alls = [a1, a2, a3]
for a in alls:
print(a)
我们使用 range() 生成多个字典,将所有字典添加到一个列表中
alls = []
for a_num in range(30):
new_a = {'color': 'green', 'points': a_num}
alls.append(new_a)
print("Total number of alls : " + str(len(alls)))
在实际应用中,经常需要在列表中包含大量的字典,而其中每个字典都包含特定对象的众多对象。
5.4.2 在字典中存储列表
有时候,需要将列表存储在字典中,而不是将字典存储在列表中。
pizza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}
for topping in pizza['toppings']:
print(topping)
每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。例如:之前有一个例子中,每个人如果有多种喜欢的语言,将他们打印出来,可以这样做:
favorite_languages = {
'jen': ['python', 'java'],
"kings": ['java', 'c', 'scala'],
'elong': ['java', '.net'],
'phl': ['php', 'python'],
}
for name, languages in favorite_languages.items():
print("\n" + name.title() + "`s favorite language are: ")
for language in languages:
print("\t" + language.title())
当然,上面的示例中,有可能有人只喜欢一个语言,或者没有喜欢的语言。所以,这时候可以在其中嵌套if 语句进行判断,判断当前遍历的值的长度,进而得到不同的结果。这些都是可以在实际应用中灵活应用的。
5.4.3 在字典中存储字典
Python 中可以字典中嵌套字典,但是这样做时,代码可能会变得复杂起来。例如:如果有多个网站用户,每个都有独特的用户名,可以在字典中将用户名作为键,然后将每位用户的信息存储在一个字典中,并将该字典作为与用户名相关联的值。在下面的程序中,对于每个用户,我们都存储其中的三项信息:名、姓和居住地;为了访问这些信息,我们需要遍历所有的用户名,并访问与每个用户名相关联的信息
users = {
'aaa': {
'first': 'aaax',
'last': 'aaay',
'location': 'jiangXi',
},
'bbb': {
'first': 'bbbx',
'last': 'bbby',
'location': 'GuangDong',
},
}
for username, userinfo in users.items():
print("\n" + username.title())
print("\t" + userinfo['first'] + " : " + userinfo['last'] + " : " + userinfo['location'])
for username, userinfo in users.items():
print("\n" + username.title())
for key, value in userinfo.items():
print("\t" + key + " : " + value)
这里需要注意:表示每位用户的字典的结构都相同,虽然Python 并没有这样的要求,但是这样使得嵌套的字典处理起来更容易。但是如果表示每位用户的字典都包含不同的内容(键),就要使用双重 for 循环进行遍历,不过这样也使for 循环内部的代码更加复杂。
5.5 小结
在本章中,我们学习了怎么定义字典;如果使用存储在字典中的信息;如何访问和修改字典中的元素;如何遍历字典中的所有键值对、所有的键和所有的值;字典和列表中的嵌套。
第六章、用户输入和while循环
大多数程序都旨在解决最终用户的问题,为此通常需要从用户那里获取一些信息。例如:假设有人要判断自己是否到了可以上网的年龄,要编写这样的程序,就需要知道用户的年龄,这样才能得出答案。因此,这种程序需要让用户输入自己的年龄,才能判断用户是否到了可以上网的年龄,在得出结果。
6.1 input() 函数的工作原理
input() 函数让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python 将其存储在一个变量中,以方便你使用
。例如:下面的程序中,让用户输入一些文本,再将这些文本呈现给用户:
message = input("Tell me something, and I repeat ot back to you: ")
print(message)
函数 input() 接受一个参数:即要向用户显示的提示或说明,让用户知道该如何做。在这个示例中,Python 运行第一行代码时,用户将看到提示,此时,程序不会继续执行下去,而是等待用户输入数据,并在用户按回车键后继续运行。
6.1.1 编写清晰的程序
每当你使用 input() 函数时,都应制定清晰而易于明白的提示,准确的指出你希望用户该做怎样的操作以及输入什么样的信息。
name = input("Please enter your name: ")
print("Hello, " + name + "!")
通过在提示末尾包含一个空格,可将提示和用户输入的信息分开,让用户清楚地知道其输入始于何处。
有时候,提示可能超过一行。这种情况下,可将提示存储在一个变量中,再将该变量传递给 input() 函数
prompt = "If you tell us who you are, we can personalize the message you see."
prompt += "\n What is you first name? "
name = input(prompt)
print("\nHello, " + name + "!")
6.1.2 使用 int() 来获取数值
使用 input() 函数时,Python 将用户输入的信息解读为字符串,所以如果你需要的是用户输入的数值作为数字使用,就会出现错误,当然,如果你只是将信息输出,那么并不会出现问题。
age = input("How old are you? ")
age = int(age)
if age >= 18:
print("you are do it.")
else:
print("you can`t do it.")
6.1.3 求模运算符
处理数值信息时,求模运算符(%)是一个很有用的工具,它将两个数相除并返回余数。求模运算最常见的运用之一就是用该运算来判断一个数是奇数还是偶数。
number = input("Enter a number, and I`ll tell you if it`s even or odd: ")
number = int(number)
if number % 2 == 0:
print("\nThe number " + str(number) + "is even.")
else:
print("\nThe number " + str(number) + "is odd.")
6.1.4 在 Python2.7 中获取输入
如果你使用的Python 版本是 2.7,就应该使用 raw_input() 函数,而不是使用 input() 函数,因为该版本中,raw_input() 函数才是将输入解读为字符串;而 input() 函数在该版本中是将用户输入解读为 Python 代码,并尝试运行他们。因此,最好的结果是出现错误,指出 Python 不明白输入的代码,而最糟糕的是,将运行你原本无意运行的代码。
6.2 while 循环简介
for 循环用于针对集合中的每个元素都一个代码块,而 while 循环不断地运行,知道指定的条件不满足为止。
6.2.1 使用 while 循环
例如:使用 while 循环来输出 1~5
num = 1
while num <= 5:
print(num)
num += 1
6.2.2 让用户选择何时退出循环
可以使用 while 循环让程序在用户愿意时不断地运行,如下面的程序所示:我们在其中定义了一个退出的标识,只要用户输入不是该值,程序就会一直运行下去
word = "\nTell me something, and I will repeat it back to you: "
word += "\nEnter 'quit' to end the program. "
message = ""
while message != 'quit':
message = input(word)
if message != 'quit':
print(message)
6.2.3 使用标志
在前一个示例中,我们让程序在满足指定条件时就执行特定的任务。但在更复杂的程序中,很多不同的事件都会导致程序停止运行,在这种情况下,该怎么办呢?导致程序结束的事件有很多时,如果一条 while 语句中检查所有这些条件,将既复杂又困难。在要求很多条件都满足才继续运行的程序中,可定义一个变量,用于判断整个程序是否处于活动状态。这个变量被称为标志,充当了程序的交通信号灯。你可以让程序在标志为 True 时继续运行,并在任何事件导致标志的值为 False 时让程序停止运行。这样,在 while 语句中就只需要检查一个条件——标志的当前值是否为 True,并将所有测试(是否发生了应将标志设置为 False 的事件)都放在其他地方,从而让程序变得更为整洁。
word = "\nTell me something, and I will repeat it back to you: "
word += "\nEnter 'quit' to end the program. "
active = True
while active:
message = input(word)
if message == 'quit':
active = False
else:
print(message)
我们将变量 active 设置成了 True,让程序最初处于活动状态。这样做简化了 while 语句,因为不需要在其中做任何比较——相关的逻辑由程序的其他部分处理。只要变量 active 为 True,循环就将继续运行。
6.2.4 使用 break 退出循环
如果想要立即退出 while 循环,不再运行循环中余下的代码,也不管条件测试的结果如何,可使用 break 语句。break 语句用于控制程序流程,可以使用它来控制哪些代码将执行,哪些不需要执行,从而让程序按你的要求执行。
word = "\nTell me something, and I will repeat it back to you: "
word += "\nEnter 'quit' to end the program. "
while True:
message = input(word)
if message == 'quit':
break
else:
print(message)
注意:在任何循环中都可使用 break 语句。例如:for 循环
6.2.5 在循环中使用 continue
要返回到循环开头,并根据条件测试结果决定是否继续执行循环,可以使用 continue 语句,它不像 break 语句那样不再执行余下的代码并退出整个循环。例如:输出1~10 中的奇数
num = 0
while num <= 10:
num += 1
if num % 2 == 0:
continue
print(num)
6.2.6 避免无限循环
每个 while 循环都必须要有停止运行的途径,这样才不会没完没了的执行下去。一定要有退出循环的条件。
每个程序员都会偶尔因不小心而编写无限循环,在循环的退出条件比较微妙时尤其如此。如果程序陷入无限循环,可以按 Ctrl+C,也可以关闭显示程序输出的终端窗口(只限在终端窗口中)。
要避免编写无限循环,务必对每个 while 循环进行测试,确保它按期那样结束。如果你希望程序在用户输入特定值时结束,可运行程序并输入这样的值;如果在这种情况下程序依然没有结束,请检查程序处理这个值的方式,确认程序至少有一个这样的地方能让循环条件为 False 或让 break 语句得以执行。
6.3 使用 while 循环来处理列表和字典
到目前为止,我们每次都只处理了一项用户信息:获取用户的输入,再将输入打印出来或者作出应答;循环再次运行时,我们获悉另一个输入值并作出相应。然而,要记录大量的用户和信息,需要我们在 while 循环中使用列表和字典。
for 循环是一种遍历列表的有效方法,但在 for 循环中不应修改列表,否则导致 Python 难以跟踪其中的元素。要在遍历列表的同时对其进行修改,可使用 while 循环。通过将 while 循环同列表和字典结合起来使用,可收集、存储并组织大量输入,供以后查看和显示。
6.3.1 在列表之间移动元素
假设有一个列表,其中包含新注册但还未验证的网站用户;验证这些用户后,如何将他们移到另一个已验证用户列表中呢?一种办法是使用一个 while 循环,在验证用户的同时将其从未验证用户列表中提取出来,再将其加入到另一个已验证的用户列表中。
# 首先创建一个待验证的用户列表 和 一个用户存储已验证用户的空列表
unconfirmed_users = ['alice', 'brian', 'candace']
confirmed_users = []
# 验证每个用户,知道没有未验证的用户为止
while unconfirmed_users:
# 将每个经过验证的用户都移到已验证用户列表中
current_user = unconfirmed_users.pop()
print("Verifying user: " + current_user.title())
confirmed_users.append(current_user)
# 遍历已验证用户列表
print("\nThe following users have been confirmend: ")
for confirmed_user in confirmed_users:
print(confirmed_user.title())
- 列表的 while 循环,如果列表中只要还有元素,将会不断的运行;
- pop() 函数每次将取出列表末尾的元素,并删除该元素。
6.3.2 删除包含特定值的所有列表元素
在第三章中,我们使用函数 remove() 来删除列表中的特定值。这之所以可行,是因为要删除的值在列表中只出现了一次。如果要删除列表中所有包含特定值的元素,该如何实现呢?例如:在一个宠物列表中,其中包好多个值为”cat”的元素,可以应用 while 循环列表,每次删除一个 cat 元素,知道列表中不再包含该元素。
pets = ['dog', 'cat', 'rabbit', 'cat', 'cat']
print(pets)
while 'cat' in pets:
pets.remove('cat')
print(pets)
6.3.3 使用用户输入来填充字典
可以使用 while 循环提示用户输入任意数量的信息。下面来创建一个调查程序,其中的循环每次执行时都提示输入被调查者的名字和回答。我们将收集的数据存储在一个字典中,以便将回答同被调查者关联起来:
responses = {}
# 设置一个标志,指出调查者是否继续
polling_active = True
while polling_active:
# 提示输入被调查者的名字和回答
name = input("\nWhat is your name? ")
response = input("\nWhich mountain would you like to climb someday? ")
# 将输入信息存储在字典中
response[name] = response
# 看看是否还有人要参与调查
repeat = input("\nWould you like to let another person respond? (yes/no) ")
if repeat == 'no':
polling_active = False
# 显示调查结果
print("\n---- Poll Results ----")
for name, response in responses:
print(name + " would like to climb " + response + ".")
6.4 小结
在本章节中,学习了:如何在程序中使用 input() 来让用户输入信息;如何处理文本和数字输入,以及如何使用 while 循环让程序按用户的要求不断地运行;多种控制 while 循环流程的方式;设置活动标志、使用 break 语句以及 continue 语句;如何使用 while 循环在列表之间移动元素,以及如何从列表中删除所有包含特定值的元组;如何结合使用 while 循环列表和字典。