从上文可以看出,Python 列表是一种将元素组织在一起的方式。在编程中,你会经常想以另一种方式组织元素,即将某个值和另一个值关联起来。这种组织方式就像电话通讯录将姓名和电话号码关联起来,也像字典将单词和它们的含义关联起来。
Python 字典(dictionary)是一种将两个东西关联在一起的方式。被关联在一起的两个东西分别称为键(key)和值(value)。字典中的每个项(item)或条目(entry)都有一个键和一个值,它们合起来被称为键值对(key-value pair)。一个字典就是一些键值对的集合。
一个简单的例子就是电话通讯录。假设你想保存朋友们的电话号码。你会使用他们的姓名去查找他们的号码(希望你的朋友们没有重名的)。这个姓名就是“键”,即你会用它来查找信息,而电话号码就是“值”,即你要查找的信息。
下面是创建一个 Python 字典的方法,我们用它来存储姓名和电话号码。首先,创建一个空的字典:
>>> phoneNumbers = {}
这个代码看起来和创建列表的方式非常像,只不过它使用的是花括号而不是方括号。
然后,我们来添加一个条目:
>>> phoneNumbers[/"John/"] = /"555-1234/"
如果我们打印一下字典,它看起来是这样的:
>>> print phoneNumbers{/'John/': /'555-1234/'}
首先显示键,然后是一个冒号,再接着显示值。之所以用引号,是因为在这个例子中键和值刚好都是字符串(不是必需的)。
也可以用另一种方式来完成:
>>> phoneNumbers = {/"John/": /"555-1234/"}
我们来添加更多的条目。不像在列表中可以使用 append
,在字典中则没有用于添加新条目的方法。只需要指定新的键和值就行了:
>>> phoneNumbers[/"Mary/"] = /"555-6789/">>> phoneNumbers[/"Bob/"] = /"444-4321/">>> phoneNumbers[/"Jenny/"] = /"867-5309/"
我们来看一下整个字典:
>>> print phoneNumbers{/'Bob/': /'444-4321/', /'John/': /'555-1234/', /'Mary/': /'555-6789/', /'Jenny/': /'867-5309/'}
我们之所以创建字典,是因为我们可以在字典中查找东西。在这个例子中,我 们希望按姓名来查找电话号码。你可以这样做:
>>> print phoneNumbers[/"Mary/"]/'555-6789/'
注意,这里使用方括号来指定你想要找的条目的键。整个字典本身还是被包裹在花括号中。
字典和列表有点类似,但也有一些主要区别。这两种类型都称为“集合”(collection),也就是说,它们都是将其他类型条目集中在一起的组织方式。
它们的一些相似点:
列表和字典都可以包含任意类型(甚至包括列表和字典)的条目,所以你可以有一个包含数字、字符串、对象甚至其他集合的集合。
列表和字典都提供了在集合中查找条目的方法。
它们的一些不同点:
列表是有顺序的(ordered)。如果你按照某种顺序向列表中添加元素,这些元素就会保持这种顺序。你还可以对列表进行排序。字典是无序的(unordered)。如果你向字典中添加内容,然后打印出来,显示的顺序可能会跟添加的顺序不同。
列表中的元素是使用索引访问的,而字典中的条目是使用键来访问的:
>>> print myList[3]/'eggs/'>>> print myDictionary[/"John/"]/'555-1234/'
前面提到过,在 Python 中很多东西都是对象,列表和字典也是。所以列表和字典都有一些使用点号表示法来使用的方法。
keys
方法会列出字典中所有的键:
>>> phoneNumbers.keys[/'Bob/', /'John/', /'Mary/', /'Jenny/']
values
方法会列出字典中所有的值:
>>> phoneNumbers.values[/'444-4321/', /'555-1234/', /'555-6789/', /'867-5309/']
其他的语言也有与 Python 字典类似的东西。它们通常被称为关联数组(associative array),因为它们将键和值关联在一起。你可能也会听说它们的另外一个名字——哈希表(hash table)。
和列表一样,字典中的条目也可以是任意类型,包括简单类型(整数、浮点数、字符串)和集合(列表、字典)以及复合类型(对象)。
没错,你可以在字典中包含其他的字典,正如列表中可以包含其他的列表一样。但事实上,这句话并不完全对。只有字典中的值是可以使用字典的,而键的要求更为严格一些。早先我们谈论过可变类型(mutable)与不可变类型(immutable)。字典的键只可以使用不可变类型(布尔、整数、浮点数、字符串和元组)。你不能使用一个列表或者字典来当作键,因为它们是可变类型。
我在上面提到过,字典和列表有一个不同之处,就是字典是无序的。注意,尽管 Bob 的电话是第三个被添加到字典中的,但在打印字典内容时却是第一个显示的。字典没有顺序这个概念,所以对字典进行排序是没有意义的。但有时你希望将字典中的内容按照某种顺序显示出来。虽然字典没有顺序,但可以对列表排序,所以当你拿到键的列表后,就可以对键进行排序,然后按照键的顺序显示字典内容。你可以使用 sorted
函数来对字典的键排序,像下面这样:
>>> for key in sorted(phoneNumbers.keys):print key, phoneNumbers[key]Bob 444-4321Jenny 867-5309John 555-1234Mary 555-6789
这和你在列表中看到的 sorted
函数是一样的。如果你细想一下,会发现它是有效的,因为字典的键的集合是一个列表。
那么,如果你想将字典的值(而不是键)按某种顺序输出该怎么办呢?在电话通讯录的例子中,就是按照电话号码从小到大输出。字典的查找过程是单向的,这意味着只能用键去查找值,而不能反过来。所以对值排序会有些困难。但这仍然是可以做到的,只是需要做更多的工作:
>>> for value in sorted(phoneNumbers.values):for key in phoneNumbers.keys: if phoneNumbers[key] == value:print key, phoneNumbers[key]Bob 444-4321John 555-1234Mary 555-6789Jenny 867-5309
我们首先取得排序之后的值的列表,然后针对列表中的每个值,循环遍历字典中的所有键,直到找到与该值关联的键。
下面是字典可以做的其他一些事情。
使用
del
删除一个条目:>>> del phoneNumbers[/"John/"]>>> print phoneNumbers{/'Bob/': /'444-4321/', /'Mary/': /'555-6789/', /'Jenny/': /'867-5309/'
使用
clear
删除所有条目(清空字典):>>> phoneNumbers.clear>>> print phoneNumbers{}
使用
in
确定某个键在字典中是否存在:>>> phoneNumbers = {/'Bob/':/'444-4321/', /'Mary/':/'555-6789/',/'Jenny/':/'867-5309/'}>>> /"Bob/" in phoneNumbersTrue>>> /"Barb/" in phoneNumbersFalse
字典在 Python 代码中使用得很广泛。
这些当然不是有关 Python 字典的全部内容,但你应该对其有了大致的了解,这样你就可以在代码中使用字典,也可以认出在其他代码中出现的字典。
你学到了什么
在这一章,你学到了以下内容。
列表是什么。
如何向列表中增加元素。
如何从列表删除元素。
如何确定列表是否包含某个值。
如何对列表排序。
如何建立列表的副本。
元组。
双重列表。
Python 字典。
测试题
1. 向列表增加元素有哪些方法?
2. 从列表删除元素有哪些方法?
3. 要得到一个列表的有序副本,但又不能改变原来的列表,有哪两种方法?
4. 怎样得出某个值是否在列表中?
5. 如何确定某个值在列表中的位置?
6. 什么是元组?
7. 如何建立双重列表?
8. 如何从一个双重列表中得到一个值?
9. 什么是字典?
10. 如何向字典中增加项?
11. 怎样使用键去查找一个条目?
动手试一试
1. 写一个程序,让用户提供 5 个名字。程序要把这 5 个名字保存在一个列表中,最后打印出来。就像这样:
Enter 5 names:TonyPaulNickMichelKevinThe names are Tony Paul Nick Michel Kevin
2. 修改第 1 题的程序,要求不仅显示原来的名字列表,还要显示出排序后的列表。
3. 修改第 1 题的程序,要求只显示用户键入的第 3 个名字,就像这样:
The third name you entered is: Nick
4. 修改第 1 题的程序,让用户替换其中一个名字。用户应该能选择要替换哪个名字,然后键入新名字。最后显示这个新的列表:
Enter 5 names:TonyPaulNickMichelKevinThe names are Tony Paul Nick Michel KevinReplace one name. Which one? (1-5): 4New name: PeterThe names are Tony Paul Nick Peter Kevin
5. 编写一个字典程序,让用户可以添加单词和定义,然后可以查找这些单词。确保当要查找的单词不存在时,用户能够知晓。运行的时候,它应该是像这样的:
Add or look up a word (a/l)? aType the word: computerType the definition: A machine that does very fast mathWord added!Add or look up a word (a/l)? lType the word: computerA machine that does very fast mathAdd or look up a word (a/l)? lType the word: qwertyThat word isn/'t in the dictionary yet.