人工智能技术之字典与集合

举报
tea_year 发表于 2023/12/20 22:46:40 2023/12/20
【摘要】 本章学习目标• 理解字典的概念• 掌握字典的创建• 掌握字典的常用操作• 了解集合的概念• 熟悉集合的常用操作列表与元组都是通过下标索引元素的,由于下标不能代表具体的含义,为此Python提供了另一种数据类型——字典,这为编程带来了极大的便利。此外,Python还提供了一种数据类型——集合,其最大特点是元素不能重复出现,因此通常用来处理去重操作。6.%2 字典的概念在现实生活中,字典可以查询...


本章学习目标

• 理解字典的概念

• 掌握字典的创建

• 掌握字典的常用操作

• 了解集合的概念

• 熟悉集合的常用操作

列表与元组都是通过下标索引元素的,由于下标不能代表具体的含义,为此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)    # set1set2不相等

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.编程题

由用户输入学生学号与姓名,数据用字典存储,最终输出学生信息(按学号由小到大显示)。




    

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。