人工智能技术之字典与集合
本章学习目标
• 理解字典的概念
• 掌握字典的创建
• 掌握字典的常用操作
• 了解集合的概念
• 熟悉集合的常用操作
列表与元组都是通过下标索引元素的,由于下标不能代表具体的含义,为此Python提供了另一种数据类型——字典,这为编程带来了极大的便利。此外,Python还提供了一种数据类型——集合,其最大特点是元素不能重复出现,因此通常用来处理去重操作。
6.%2 字典的概念
在现实生活中,字典可以查询某个词的语义,即词与语义建立了某种关系,通过词的索引便可以找到对应的语义,如图6.1所示。
图6.1 字典
在Python中,字典也如现实生活中的字典一样,使用词-语义进行数据的构建,其中词对应键(key),词义对应值(value),即键与值构成某种关系,通常将两者称为键值对,这样通过键可以快速找到对应的值。
字典是由元素构成的,其中每个元素都一个键值对,具体示例如下:
student = {'name': '小千', 'id': 20190101, 'score': 98.5}
示例中,字典由3个元素构成,元素之间用逗号隔开,整体用花括号括起来。每个元素是一个键值对,键与值之间用冒号隔开,如'name':'xiaoqian','name'是键,'xiaoqian'是值。
因为字典是通过键来索引值的,所以键必须是唯一的,而值并不唯一,具体示例如下:
student = {'name': '小千', 'name': '小锋', 'score1': 98.5, 'score2': 98.5}
示例中,字典中有两个元素的键为'name',有两个元素的值为98.5。若通过print(student)输出字典,则得到以下输出:
{'name': '小锋', 'score1': 98.5, 'score2': 98.5}
从上述结果可看出,如果字典中存在相同键的元素,只会保留后面的元素。
另外,键不能是可变数据类型,如列表,而值可以是任意数据类型,具体示例如下:
student = {['name', 'alias']: '小千'} # 错误
上述语句在程序运行时会引发错误。
通过上面的学习,读者可以总结出字典的特征:
• 字典中的元素是以键值对的形式出现的。
• 键不能重复,而值可以重复。
• 键是不可变数据类型,而值可以任意数据类型。
6.%2 字典的创建
了解了字典的概念后,接下来创建一个字典,具体示例如下:
dict1 = {}
上述语句创建了一个空字典,也可以在创建字典时指定其中的元素,具体示例如下:
dict2 = {'name': '小千', 'id': 20190101, 'score': 98.5}
字典中值可以取任何数据类型,但键必须是不可修改的,如字符串、元组,具体示例如下:
dict3 = {20190101: ['小千', 100], (1101, '大一'):['小锋', 99]}
此外,还可以使用dict()来创建字典,如例6-1所示。
例6-1
1 items = [('name', '小千'), ('score', 98)] # 列表
2 d = dict(items)
3 print(d)
运行结果如图6.2所示。
图6.2 运行结果
在例6-1中,第1行定义一个列表,列表中的每个元素为元组。第2行通过dict()将列表转换为字典并赋值给d。
此外,dict()还可以通过设置关键字参数创建字典,如例6-2所示。
例6-2
1 d = dict(name = '小千', score = 98)
2 print(d)
运行结果如图6.3所示。
图6.3 运行结果
在例6-2中,第1行通过设置dict()中参数来指定创建字典的键值对。
6.%2 字典的常用操作
在实际开发中,字典使得数据表示更加完整,因此它是应用最广的一种数据类型。如果读者想要熟练运用字典,就必须熟悉字典中常用的操作。
6.3.1 计算元素个数
字典中元素个数可以通过len()函数来获取,如例6-3所示。
例6-3
1 dict = {'qfedu':'千锋教育', 'codingke':'扣丁学堂'}
2 print(len(dict))
运行结果如图6.4所示。
图6.4 运行结果
在例6-3中,第2行通过len()函数计算元素个数并输出。
6.3.2 访问元素值
列表与元组是通过下标索引访问元素值,而字典是通过元素的键来访问值,如例6-4所示。
例6-4
1 dict = {'qfedu':'千锋教育', 'codingke':'扣丁学堂'}
2 print(dict['qfedu'])
3 print(dict['codingke'])
运行结果如图6.5所示。
图6.5 运行结果
在例6-4中,第2行与第3行通过键访问所对应的值并通过print()函数输出。如果访问不存在的键,则运行时程序会报错。
有时不确定字典中是否存在某个键而又想访问该键对应的值,则可以通过get()函数,如例6-5所示。
例6-5
1 dict = {'qfedu':'千锋教育', 'codingke':'扣丁学堂'}
2 name1 = dict.get('goodProgrammer') # 不存在该键时,返回None,而不是报错
3 print(name1)
4 name2 = dict.get('qfedu') # 存在该键时,返回对应的值
5 print(name2)
运行结果如图6.6所示。
图6.6 运行结果
在例6-5中,第2行通过get()函数获取'goodProgrammer'对应的值,字典中不存在这个键,此时返回None,而不是报错。第4行通过get()函数获取'qfedu'对应的值,字典中存在这个键,此时返回'千锋教育'。
6.3.3 修改元素值
字典中除了通过键访问值外,还可以通过键修改值,如例6-6所示。
例6-6
1 std = {'name':'小千', 'score':100}
2 print(std)
3 std['name'] = '小锋'
4 std['score'] = 99
5 print(std)
运行结果如图6.7所示。
图6.7 运行结果
在例6-6中,第3行与第4行通过键修改所对应的值。从运行结果可发现,修改后字典中的元素发生了变化。
6.3.4 添加元素
通过键修改值时,如果键不存在,则会在字典中添加该键值对,如例6-7所示。
例6-7
1 std = {'name':'小千', 'score':100}
2 std['name'] = '小锋' # 该键存在,修改键对应的值
3 std['age'] = 18 # 该键不存在,添加该键值对
4 print(std)
运行结果如图6.8所示。
图6.8 运行结果
在例6-7中,第2行修改键'name'所对应的值为'小锋',第3行将键值对'age':18添加到字典中。
此外,还可以通过update()函数修改某键对应的值或添加元素,如例6-8所示。
例6-8
1 std = {'name':'小千', 'score':100}
2 new = {'name':'小锋'}
3 std.update(new) # 修改键所对应的值
4 print(std)
5 add = {'age':18}
6 std.update(add) # 添加元素
7 print(std)
运行结果如图6.9所示。
图6.9 运行结果
在例6-8中,第3行修改键'name'所对应的值为'小锋',第6行将键值对'age':18添加到字典std中。
6.3.5 删除元素
删除字典中的元素可以通过“del 字典名[键]”实现,如例6-9所示。
例6-9
1 std = {'name':'小千', 'score':100}
2 del std['score']
3 print(std)
运行结果如图6.10所示。
图6.10 运行结果
在例6-9中,第2行通过del删除字典中的键值对'score':100。
此外,还可以通过pop()函数删除指定元素并返回该元素,如例6-10所示。
例6-10
1 std = {'name':'小千', 'score':100}
2 std.pop('score')
3 print(std)
运行结果如图6.11所示。
图6.11 运行结果
在例6-10中,第2行通过pop()函数删除字典中的键值对'score':100。
如果想删除字典中所有元素,则可以使用clear()实现,如例6-11所示。
例6-11
1 std = {'name':'小千', 'score':100}
2 std.clear()
3 print(std)
运行结果如图6.12所示。
图6.12 运行结果
在例6-11中,第2行通过clear()删除字典中所有的元素。
6.3.6 复制字典
有时需要将字典复制一份以便用于其他操作,这样原字典数据不受影响,这时可以通过函数copy()来实现,如例6-12所示。
例6-12
1 std = {'name':'小千', 'score':100}
2 s = std.copy()
3 del s['score']
4 print(s)
5 print(std)
运行结果如图6.13所示。
图6.13 运行结果
在例6-12中,第2行通过copy()将字典std中数据复制一份赋值给字典s。第3行删除字典s中元素'score':100。从运行结果可发现,对字典s的操作并不会影响字典std。
6.3.7 成员运算
字典中可以使用成员运算符(in、not in)来判断某键是否在字典中,如例6-13所示。
例6-13
1 std = {'name':'小千', 'score':100}
2 print('name' in std)
3 print('score' not in std)
运行结果如图6.14所示。
图6.14 运行结果
在例6-13中,第2行与第3行通过成员运算符判断键是否在字典中。注意该运算符只能判断键是否在字典中,不能判断值是否在字典中。
6.3.8 设置默认键值对
有时需要为字典中某个键设置一个默认值,则可以使用setdefault()函数,如例6-14所示。
例6-14
1 std = {'name':'小千', 'score':100}
2 name = std.setdefault('school', '千锋教育')
3 print(name, std)
4 name = std.setdefault('school', '扣丁学堂')
5 print(name, std)
运行结果如图6.15所示。
图6.15 运行结果
在例6-14中,程序执行第2行时,键'school'不在字典中,此时setdefault()函数向字典中加入键值对'school': '千锋教育',并将'千锋教育'作为返回值赋值给name。程序执行第4行时,键'school'已在字典中,此时setdefault()函数只将该键对应的值'千锋教育'作为返回值赋值给name。
6.3.9 获取字典所有键
keys()函数可以获取字典中所有元素的键,如例6-15所示。
例6-15
1 std = {'name': '小千', 'score': 100}
2 print(std.keys())
3 for key in std.keys():
4 print(key)
运行结果如图6.16所示。
图6.16 运行结果
在例6-15中,第2行打印key()函数的返回值,第3行到第4行通过for循环遍历keys()函数返回值并打印每一项。
6.3.10 获取字典所有值
values()函数可以获取字典中所有元素键所对应的值,如例6-16所示。
例6-16
1 std = {'name': '小千', 'score': 100}
2 print(std.values())
3 for value in std.values():
4 print(value)
运行结果如图6.17所示。
图6.17 运行结果
在例6-16中,第2行打印values()函数的返回值,第3行到第4行通过for循环遍历values()函数返回值并打印每一项。
6.3.11 获取字典所有键值对
items()函数可以获取字典中所有的键值对,如例6-17所示。
例6-17
1 std = {'name': '小千', 'score': 100}
2 print(std.items())
3 for item in std.items():
4 print(item)
运行结果如图6.18所示。
图6.18 运行结果
在例6-17中,第2行打印items()函数的返回值,第3行到第4行通过for循环遍历items()函数返回值并打印每一项。从运行结果可看出,每一项是由键与值组成的元组。
此外,items()函数与for循环结合可以遍历字典中的键值对,如例6-18所示。
例6-18
1 std = {'name': '小千', 'score': 100}
2 for key, value in std.items():
3 print('key = %s, value = %s'%(key, value))
运行结果如图6.19所示。
图6.19 运行结果
在例6-18中,第2行到第3行通过for循环遍历items()函数返回值并将每一项中的键与值分别赋值给key与valule。
6.3.12 随机删除元素
popitem()函数可以随机返回并删除一个元素,如例6-19所示。
例6-19
1 std = {'name': '小千', 'score': 100, 'school':'千锋教育'}
2 item = std.popitem()
3 print(item, std)
运行结果如图6.20所示。
图6.20 运行结果
在例6-19中,第2行执行popitem()函数后,删除字典中最后一个元素。注意该函数返回一个元组。
此外,pop()函数可以根据指定的键删除元素,如例6-20所示。
例6-20
1 std = {'name': '小千', 'score': 100, 'school':'千锋教育'}
2 item = std.pop('score')
3 print(item, std)
运行结果如图6.21所示。
图6.21 运行结果
在例6-20中,第2行执行pop()函数后,删除字典中键为'score'的元素。注意该函数返回键所对应的值,而不是键值对。
6.%2 集合的概念
集合是由一组无序排列且不重复的元素组成,具体示例如下:
set1 = {1, 2, 'a'}
集合使用花括号表示,元素类型可以是数字类型、字符串、元组,但不可以是列表、字典,具体示例如下:
set2 = {2 , ['a', 1]} # 错误,元素包含列表
set3 = {2 , {'a':1}} # 错误,元素包含字典
set3 = {2 , ('a', 1)} # 正确,元素包含元组
使用花括号创建的集合属于可变集合,即可以添加或删除元素。此外,还存在一种不可变集合,即不允许添加或删除元素。
接下来演示创建这两种集合的方法,如例6-21所示。
例6-21
1 set1 = set('xiaoqian') # 通过set()创建可变集合
2 print(type(set1), set1)
3 set2 = set(('xiaoqian', 'xiaofeng'))
4 set3 = set(['xiaoqian', 'xiaofeng'])
5 print(set2, set3)
6 fset1 = frozenset('xiaofeng') # 通过frozenset()创建不可变集合
7 print(type(fset1))
8 print(fset1)
运行结果如图6.22所示。
图6.22 运行结果
在例6-21中,第1行通过set()函数创建可变集合并将字符串中去重后的字符作为集合的元素。第3行将元组作为set()函数的参数创建集合set2。第4行将列表作为set()函数的参数创建集合set3。第6行通过frozenset ()函数创建不可变集合。
集合的一个重要用途是将一些数据结构中的重复元素去除,如例6-22所示。
例6-22
1 list1 = [1, 2, 3, 4, 3, 2, 1]
2 set1 = set(list1) # 将列表转换为集合并去重
3 list2 = list(set1) # 将集合转换为列表
4 print(list2)
运行结果如图6.23所示。
图6.23 运行结果
在例6-22中,第2行通过set()函数将列表转换为集合,集合中的元素是不重复的。第3行通过list()函数将集合转换为列表,此时列表中的元素也是不重复的。
6.%2 集合的常用操作
同其他数据类型类似,集合也有一系列常用的操作,例如添加元素、删除元素等。通过这些操作,编程者可以很方便地处理集合。
6.5.1 添加元素
集合中添加元素可以使用add()和update()函数,如例6-23所示。
例6-23
1 set1, set2 = {1, 2, 3}, {3, 4, 5, 6}
2 set1.add(4)
3 print(set1)
4 set1.update(set2)
5 print(set1)
运行结果如图6.24所示。
图6.24 运行结果
在例6-23中,第2行通过add()函数将元素4添加到集合set1,第4行通过update()函数将集合set2中的元素添加到集合set1。
6.5.2 删除元素
集合中删除元素可以使用remove()和discard()函数,如例6-24所示。
例6-24
1 set1 = {1, 2, 3, 4}
2 set1.remove(3) # 删除不存在元素时报错
3 set1.discard(4) # 删除不存在元素时不会报错
4 set1.discard(5)
5 print(set1)
6 set1.clear() # 清空集合
7 print(set1)
运行结果如图6.25所示。
图6.25 运行结果
在例6-24中,注意remove()和discard()函数的区别。
6.5.3 集合运算
集合可以参与多种运算,如表6.1所示。
表6.1 集合中的运算
运算 |
说明 |
运算 |
说明 |
x in set1 |
检测x是否在集合set1中 |
set1 | set2 |
并集 |
set1 == set2 |
判断集合是否相等 |
set1 & set2 |
交集 |
set1 <= set2 |
判断set1是否是set2的子集 |
set1 - set2 |
差集 |
set1 < set2 |
判断set1是否是set2的真子集 |
set1 ^ set2 |
对称差集 |
set1 >= set2 |
判断set1是否是set2的超集 |
set1 |= set2 |
将set2的元素并入set1 |
set1 < set2 |
判断set1是否是set2的真超集 |
|
|
接下来演示这些运算的用法,如例6-25所示。
例6-25
1 set1, set2 = {1, 2, 3}, {2, 3, 4}
2 print(1 in set1) # set1中包含元素1
3 print(set1 == set2) # set1与set2不相等
4 print(set1 > set2) # set2不是set1的子集
5 print(set1 >= set2) # set2不是set1的真子集
6 print(set1 | set2) # 并集
7 print(set1 & set2) # 交集
8 print(set1 - set2) # 差集
9 print(set1 ^ set2) # 对称差集
10 set1 |= set2 # 将set2并入set1
11 print(set1)
运行结果如图6.26所示。
图6.26 运行结果
在例6-25中,除了set1 |= set2外,所有的运算都不会影响set1与set2中的元素。
除了上述运算符外,还可以通过union()、intersection()与difference()函数实现集合的并集、交集与差集,如例6-26所示。
例6-26
1 set1, set2 = {1, 2, 3}, {2, 3, 4}
2 print(set1.union(set2)) # 并集
3 print(set1.intersection(set2)) # 交集
4 print(set1.difference(set2)) # 差集
运行结果如图6.27所示。
图6.27 运行结果
在例6-26中,这三个函数的调用都不会影响set1与set2中的元素。
6.5.4 集合遍历
集合可以通过for循环遍历其中的元素,如例6-27所示。
例6-27
1 set1 = {1, 2, 3, 4}
2 for num in set1:
3 print(num, end = ' ')
运行结果如图6.28所示。
图6.28 运行结果
在例6-27中,通过for循环遍历集合中的元素。
6.%2 字典推导与集合推导
字典推导与列表推导相似,它将推导出一个字典,具体示例如下:
dict1 = {x : x * x for x in range(5)}
字典解析使用花括号包围,并且需要两个表达式,一个生成key,一个生成value,两个表达式之间使用冒号分割,结果返回字典。若通过print()打印dict1,则输出结果为:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
上述就是一个简单的字典推导,接下来演示稍微复杂的字典推导,如例6-28所示。
例6-28
1 dict1 = [(86, 'china'), (91, 'india'), (1, 'united states')]
2 dict2 = {country: code for code, country in dict1}
3 print(dict2)
4 print({code: country for country, code in dict2.items() if code < 90})
运行结果如图6.29所示。
图6.29 运行结果
在例6-28中,第2行通过字典推导将dict1中的值与键作为dict2中的键与值,第4行通过字典推导筛选键值小于90的元素并返回一个新字典。
集合推导也与列表推导相似,只需将中括号改为花括号,具体示例如下:
set1 = {x * x for x in range(5)}
集合推导将返回一个集合。若通过print()打印set1,则输出结果为:
{0, 1, 4, 9, 16}
接下来演示集合推导的用法,如例6-29所示。
例6-29
1 strings = ['Python', 'HTML', 'PHP', 'VR', 'Java', 'C++']
2 print ({len(s) for s in strings})
运行结果如图6.30所示。
图6.30 运行结果
在例6-29中,第2行使用集合推导创建一个字符串长度的集合,字符串长度相同的值只会在集合中出现一次。
6.%2 小案例
6.7.1 案例一
小千、小锋与小明在扣丁学堂上学习几门不同的IT课程,每人已经学习的课时数也不同,现用字典保存每人学习的课程与课时数,统计Python课程的总课时数,具体实现如例6-30所示。
例6-30
1 std = {
2 '小千':{'Python':10, 'PHP':5},
3 '小锋':{'Python':8, 'UI':'4'},
4 '小明':{'Python':2, 'UI':5, 'PHP':'1'},
5 }
6 num = 0
7 for value in std.values():
8 num += value.get('Python', 0)
9 print('Python课程总课时数为%d'%num)
运行结果如图6.31所示。
图6.31 运行结果
在例6-30中,使用字典的嵌套字典保存每人学习的课程与课时数,然后通过for循环遍历字典中的值来统计Python的总课时数。
6.7.2 案例二
输入一句英文,统计英文中出现的字母及次数,使用字典保存每个字母及次数,具体实现如例6-31所示。
例6-31
1 s = input('请输入一句英文:')
2 s = s.upper()
3 dict1 = {chr(n): 0 for n in range(65, 91)}
4 for char in s:
5 if 'A' <= char <= 'Z':
6 dict1[char] += 1
7 list1 = list(dict1.items())
8 for ele in list1:
9 if ele[1] != 0:
10 print(ele[0] + ':', ele[1] )
运行结果如图6.32所示。
图6.32 运行结果
在例6-31中,第3行使用字典推导生成一个字典,其中键为字母,值为0。第4行通过for循环遍历输入的字符串,每遍历一个字母相应的字典中对应值加1。第7行将生成一个列表,列表中每个元素为元组。
6.%2 本章小结
本章主要介绍了Python中的字典与集合,两者都使用花括号表示。字典中每个元素都是由键与值组成的,其中键为不可变类型,而值可以为任意类型。字典在实际编程中经常使用,读者应熟练掌握其常用操作。集合是由一组无序排列且不重复的元素组成,经常用于去重。集合在实际编程中使用不多,读者只需了解即可。
6.%2 习题
1.填空题
(1) 字典使用 括号表示。
(2) 集合使用 括号表示。
(3) 字典中每个元素都是由 组成的。
(4) 函数可以获取字典中所有的键值对。
(5) 函数创建一个不可变集合。
2.选择题
(1) 下列属于字典的是( )。
A.{1:2, 3:4} B.[1, 2, 3, 4]
C.{1, 2, 3, 4} D.(1, 2, 3, 4)
(2) 下列不可以作为字典键的是( )。
A.4 B.(3, 2, 4, 1)
C.[4, 1, 3, 2] D.'4'
(3) 下列可以获取字典中所有值的是( )。
A.values() B.keys()
C.get() D.getValues()
(4) 下列不能使用下标运算的是( )。
A.列表 B.字符串
C.元组 D.集合
(5) 集合中元素类型不能为( )。
A.元组 B.字符串
C.数字 D.字典
3.思考题
(1) 简述字典的特征。
(2) 简述字典与集合的区别。
4.编程题
由用户输入学生学号与姓名,数据用字典存储,最终输出学生信息(按学号由小到大显示)。
- 点赞
- 收藏
- 关注作者
评论(0)