字典可以用下面的方式创建。

phoneBook = {"Bill":"1234", "Mike":"4321", "John":"6645","Mary":"7753"}

我们可以看到,一个字典是用一对大括号来创建的,键与值之间用冒号(:)分隔,每一对键值之间用逗号(,)分隔。如果大括号中没有任何的值,就是一个空的字典。

在字典中,键是唯一的,这样才能通过键唯一定位某一个值。当然,如果键不唯一,那么程序也不会抛出异常,只是相同的键值会被覆盖。

phoneBook = {"Bill":"1234", "Bill":"4321", "John":"6645","Mary":"7753"}

我们可以看到上面的这行代码定义的字典中,前两对键值中的键是相同的,如果通过Bill定位,那么查到的值是"4321",而不是"1234"。

1. dict函数

可以用dict函数,通过其他映射(如其他的字典)或键值对的序列建立字典。

items = [["Bill","1234"], ("Mike","4321"),["Mary", "7753"]]d = dict(items)# 运行结果:{'Bill': '1234', 'Mike': '4321', 'Mary': '7753'}print(d)

我上面的代码可以看出,为dict函数传入了一个列表类型参数值,列表的每一个元素或者是一个列表,或者是一个元组。每一个元素值包含两个值。第1个值表示键,第2个值表示值。这样dict函数就会将每一个items列表元素转换为字典中对应的一个键值。

dict函数还可以通过关键字参数来创建字典。

items = dict(name = "Bill", number = "5678", age = 45)# 运行结果:{'name': 'Bill', 'number': '5678', 'age': 45}print(items)

dict函数如果不指定任何参数,那么该函数会返回一个空的字典。

本例通过控制台输入一组key和value,首先通过每一对key-value创建一个列表,并将这个列表放到一个大的列表(items)中。最后使用dict函数将items转换为字典,并在控制台输出这个字典。

items = [] # 定义一个空的列表while True: key = input("请输入Key:") # 从控制台输入一个key if key == "end": # 当key值为"end"时退出循环 break; value = input("请输入value:") # 从控制台输入一个value keyValue = [key, value] # 用key和value创建一个列表 items.append(keyValue) # 将key-value组成的列表添加到items中d = dict(items) # 使用dict函数将items转换为字典print(d) # 在控制台输出字典

程序运行结果如下图所示。

2. 字典的基本操作

字典的很多操作与列表类似,如下面的一些操作仍然适合于字典。

• len(dict):返回字典dict中元素(键值对)的数量。

• dict[key]:返回关联到键key上的值,对于列表,key就是索引。

• dict[key] = value:将值value关联到键key上。

• del dict[key]:删除键为key的项。

• key in dict:检查dict中是否包含有键为key的项。

尽管字典和列表有很多特性相同,但也有下面的一些重要区别。

• 键类型:字典的键可以是任意不可变类型,如浮点数、元组、字符串等,而列表的key只能是整数类型。

• 自动添加:字典可以通过键值自动添加新的项,也就是说,进行dict[key] = value操作时,如果key在字典dict中不存在,那么就会在dict中添加一个新的元素(键-值对)。而在列表中,必须要使用append方法或insert方法才能在列表中添加新的元素。

• 查找成员:在字典中使用key in dict操作,查找的是key,而不是value。在列表中使用key in dict操作,查找的是值,而不是索引。对于列表来说,key就代表值。尽管字典和列表在引用其中的值时都是用dict[key],但key in dict操作的含义是不同的。

注意:由于字典中的元素是通过一定的数据结构(排序树或其他数据结构)存储的,所以在字典中查找key要比在字典中查找值更高效,数据量越大,这种效果越明显。

本例演示了字典的键类型,为字典添加新的元素(键值对),以及如何使用in操作符在字典中查找指定的key。在演示in操作符时,在名为IDEs的字典中添加各种IDE支持的编程语言以及所属机构,然后通过控制台输入要查找的IDE名称,并指定要查找IDE支持的编程语言或所属机构,最后在控制台输出结果。

dict = {} # 定义一个字典dict[20] = "Bill" # 向字典dict中添加整数类型的keydict["Mike"] = {'age':30,'salary':3000} # 向字典dict中添加字符串类型的keydict[(12, "Mike", True)] = "hello" # 向字典dict中添加元组类型的keyprint(dict) # 输出字典dict中的所有元素#list = [] # 定义一个列表#list[30] = "hello" # 索引为30的元素并不存在,所以会抛出异常IDEs = { # 定义一个字典 'eclipse': { 'languages':['Java', 'Python', 'JavaScript','PHP'], 'organization':'Eclipse基金会' }, 'visualstudio': { 'languages':['C#','C++', 'VB.NET'], 'organization':'微软' }, 'webstorm': { 'languages':['JavaScript'], 'organization':'JetBrains' } }labels = { # 定义一个字典,用于存储显示的标签 'languages':'支持的编程语言', 'organization':'所属机构' }IDE = input('请输入IDE的名字:') # 从控制台输入一个IDE的名字findIDE = IDE.replace(" ", "").lower() # 去除IDE名字中的所有空格,并将其转换为小写# 从控制台输入lang或org,表示要查询IDE支持的编程语言或所属机构choice = input('要查询IDE支持的编程语言(lang)还是所属组织机构(org)?')if choice == "lang": key = 'languages'if choice == "org": key = 'organization'# 在IDEs字典中查找指定的IDE,如果找到,就输出查询结果。if findIDE in IDEs: print("{}{}是{}.".format(IDE, labels[key], IDEs[findIDE][key]))

程序运行结果如下图所示。

在上面的代码中,从字典IDEs中查找指定IDE时,首先将输入的IDE名字中所有的空格去掉,然后又将其中所有的字母都转换为小写。而IDEs中保存的key也符合这个规则,也就是IDE名字全部用小写,而且中间没有空格。由于在输入IDE名字时,可能会输入多个空格,名字也可能带有大小写字母,所以将输入的IDE名字转换为IDEs中key的命名规则,以保证输入不同格式的IDE名字都可以查到相应的IDE。例如,输入“Visual Studio”、“visual studio”、“VisualStudio”都可以查询到Visual Studio的相应信息。

3. 字典的格式化字符串

在前面的文章讲过使用百分号(%)配合元组对字符串进行格式化的方式。在字符串中使用%s、%d等格式表示要替换的值,这个字符串可以称为模板,然后用字符串模板与元组通过%进行格式化。

'xyz %d abc %s' % (20,'ok')

如果使用字典对字符串进行格式化,要比使用元组更酷。因为在字符串模板中可以用命名的方式指定格式化参数。在Python2.x中,仍然可以使用%运算符和字典对字符串进行格式化,不过在Python3.x中,改用了字符串的format_map方法,而且格式化参数需要用一对花括号({})括起来,格式化字符串的具体使用方式见例6.3。

本例演示了如何使用字符串的format_map方法和字典对字符串进行格式化,并与使用元组和%对字符串进行格式化的方式进行对比。

values1 = (1,3,"hello") # 定义一个格式化参数元组zheyangzuostr1 = "abc %d, xyz %d, %s world" # 定义一个字符串模板print(str1 % values1) # 使用%和元组格式化字符串# 定义一个格式化参数字典values2 = {'title':'极客起源', 'url':'https://geekori.com', 'company':'欧瑞科技'}# 定义一个字符串模板str2 = """<html> <head> <title>{title}</title> <meta charset="utf-8" /> <head> <body> <h2>{title}</h2> <a href="{url}">{company}</a> </body></html>"""print(str2.format_map(values2)) # 使用format_map方法格式化字符串

程序运行结果如下图所示。

我们可以看到,format_map方法使用的字符串模板中,格式化参数使用一对花括号({})表示,花括号里面就是格式化参数的名字,如“{title}”,这个格式化参数名也是字典中的key。使用字典提供格式化参数值的好处是不需要按字符串模板中的顺序指定格式化参数值,而且同一个格式化参数可以放在多个位置,在格式化时会替换所有同名的格式化参数。如本例中的{title}放在了两个位置。如果格式化模板中的格式化参数名在字典中未找到,系统会抛出异常。

4. 序列与迭代

之所以在这里讲序列如何在迭代中使用,是因为到现在为止,我们已经讲了三种序列:列表、元组和字典。通过不同的迭代方式,可以非常方便地对序列进行迭代。本节会为读者详细介绍Python语言中提供的各种序列迭代方式。

(1)获取字典中key的列表

在使用字典时,如果要想知道字典里有哪些key,可以直接使用for语句对字典进行遍历。

dict = {'x':1, 'y':2,'z':3}# 输出x y zfor key in dict: print(key, end=' ')

上面的代码中,key的值分别为x、y、z,因此,会输出“x y z”。

(2)同时获取字典中的key和value列表

如果要同时获取字典中的key和value,除了在上面的代码中使用dict[key]获取值外,还可以使用字典中的items方法同时获取key和value。

dict = {'x':1, 'y':2,'z':3}# 同时获取字典中的key和value# 运行结果:x 1 y 2 z 3for key,value in dict.items(): print(key, value, end=' ')(3)并行迭代

如果想同时迭代两个或多个序列,那么可以使用range函数获取序列索引的范围,然后使用for语句进行迭代。对多个序列进行迭代,一般要求序列中元素个数相同。

names = ["Bill", "Mary", "John"]ages = [30,40,20]# 运行结果:Bill 30 Mary 40 John 20for i in range(len(names)): print(names[i],ages[i], end=" ")(4)压缩序列

这里的压缩序列是指使用zip函数将两个或多个序列的对应元素作为一个元组放到一起,进行压缩的两个或多个序列的元素个数如果不相同,以元素个数最少的为准。例如,下面的2个序列如果用zip函数进行压缩,会得到一个长度为2的新序列,每一个序列元素是一个元组。

companies = ["欧瑞科技", "Google", "Facebook"]websites = ["https://geekori.com", "https://www.googel.com"]# 运行结果:('欧瑞科技', 'https://geekori.com') ('Google', 'https://www.googel.com')for value in zip(companies, websites): print(value, end =" ")

在上面的代码中,companies列表中有3个元素,而websites列表中只有两个元素, zip函数会以元素少的列表为准,因此最后的结果是以websites列表为准,得到的压缩后的列表元素只有2个元素。由于zip函数返回的序列形式比较复杂,所以不能直接使用print函数输出。

(5)反转序列迭代

通过reversed函数可以将一个序列反转,代码如下:

companies = reversed(["欧瑞科技", "Google", "Facebook"])# 运行结果:Facebook Google 欧瑞科技for value in companies: print(value, end =" ")

《Python从菜鸟到高手》已经出版,开始连载了,购买送视频课程