第五章 字典和集合
5.1 集合
5.2 字典
5.1 集合
- 集合(set)是一组对象的组合,是一个不重复的、无序的数据集合体。
- 类似数学中的集合,即包含0个或多个数据项的无序组合。可以进行交、并、差等运算。
- 集合用"{}"表示,因为是无序组合,它没有索引和位置的概念,集合中的元素可以动态增加或删除
- 可变集合元素类型只能是不可变数据类型,如整数、浮点数、字符串、元组等,而列表、字典和集合类型本身都是可变数据类型,不能作为集合的元素出现
- 由于集合元素是无序的,集合的输出顺序与定义顺序可以不一致
>>> {1,5,7}
{1, 5, 7}
>>> {1,4,2,5,4,2}
{1, 2, 4, 5}
>>> s={"abc",15,3.14,15}
>>> s
{'abc', 3.14, 15}
>>> type(s)
<class 'set'>
>>>
1 创建集合
#(1)直接给变量赋值一个集合字面量
>>> fruits={"apple","orange","pear"}
>>> fruits
{'pear', 'apple', 'orange'}
#(2)使用set()创建一个空集合
>>> emps=set( )
#(3)使用set()将列表或元组转换成集合
>>> s1=set([2,4,6,8,10,8])
>>> s1
{8, 2, 10, 4, 6}
>>> s2=set("abc")
>>> s2
{'b', 'a', 'c'}
>>> type(s)
<class 'set'>
强调
- 若emps={ } 将创建一个字典,而非创建一个集合
- 创建集合时,Python会自动消除重复的值
- 以上创建的为可变集合
#(4)创建不可变集合
>>> set3=frozenset('hello world')
>>> set3
frozenset({'l', 'w', ' ', 'e', 'd', 'r', 'h', 'o'})
>>> type(set3)
<class 'frozenset'>
>>> set4={1,2,'a',set3}
>>> set4
{1, 2, 'a', frozenset({'o', 'd', ' ', 'l', 'r', 'h', 'e', 'w'})
强调
- frozenset( )函数可以将元组、列表和字符串等类型数据转换成不可变集
2 集合的常用操作函数或方法
若s1={2,3,"a",(10,20)},s2={2,3,5,7,11}
函数或方法 | 描述 | 示例 | 结果 |
---|---|---|---|
len(s) | 返回集合中元素的数量 | len(s1) | 4 |
min(s) max(s) |
返回集合中所有能比较的元素中最小(最大)的元素 | min(s2) max(s2) |
2 11 |
sum(s) | 将集合元素求和 | sum(s2) | 28 |
s.add(x) | 若x不在集合中,将x增加到集合s中 | s2.add(13) | {2,3,5,7,11,13} |
s.remove(x) s.discard(x) |
如果x在集合s中,移除该元素;否则会产生KeyError异常(没有任何操作) | s1.remove("a") s1.remove(8) s1.discard(8) |
{2,3,(10,20)} keyError异常 无任何操作 |
s.clear() | 移除s中所有的元素 | s2.clear() | set() |
若s1={1,2,3,4},s2={1,2,3}
函数或方法 | 描述 | 示例 | 结果 |
---|---|---|---|
A.issubset(B) | 判断A是否是B的子集 | s1.issubset(s2) | False |
A.issuperset(B) | 判断A是否是B的超集 | s1.issupperset(s2) | True |
A.isdisjoint(B) | 判断A与B是否没有共同元素 | s1.isdisjoint(s2) | False |
A.union(B) | 返回A与B的并集 | s1.union(s2) | {1,2,3,4} |
A.intersection(B) | 返回A与B的交集 | s1.intersection(s2) | {1,2,3} |
A.difference(B) | 返回A与B的差集 | s1.difference(s2) | {4} |
A.symmetric_difference(B) | 返回A与B的对称差集 | s1.symmetric_difference(s2) | {4} |
3 集合的操作符
操作符及运算 | 描述 |
---|---|
A|B | A与B的并集 |
A-B | A与B的差集 |
A&B | A与B的交集 |
A^B | A与B的对称差集 |
强调
- 集合的操作逻辑与数学定义相同
>>> s1={2,3,5,7,11}
>>> s2={2,3,4,5,6,7}
>>> s1|s2
{2, 3, 4, 5, 6, 7, 11}
>>> s1&s2
{2, 3, 5, 7}
>>> s1-s2 #出现在s1但不出现在s2的元素新集合
{11}
>>> s1^s2 #返回一个s1和s2中非共同元素组成的新集合
{4, 6, 11}
操作符及运算 | 描述 |
---|---|
A==B | 判断A与B是否相等 |
A!=B | 判断A与B是否不相等 |
A<B | 判断A是否是B的真子集 |
A<=B | 判断A是否是B的子集(包括非真子集) |
A>B | 判断A是否是B的真超集 |
A>=B | 判断A是否是B的超集(包括非真超集) |
C in A | C是否是A的成员 |
C not in A | C是否不是A的成员 |
>>> s1={2,3,5,7}
>>> s2={2,3,4,5,6,7,11}
>>> s1==s2
False
>>> s1<=s2
True
>>> s2>s1
True
>>> 3 in s1
True
>>> 8 not in s2
True
4 集合的遍历
用循环实现遍历集合中的各个元素
s={2,3,5,7,11}
for i in s:
print(i)
程序运行结果
11
2
3
5
7
综合实例
【例5-1】 已知两个集合footballSet和basketballSet,分别存储选择了足球兴趣小组和篮球兴趣小组的学生姓名,请自行购建集合数据,计算并输出如下信息:
(1)选择了两个兴趣小组的学生姓名和人数
(2)仅选了一个兴趣小组的学生姓名和人数
#E5-1.py
footballSet={'Tom','Lily','Rose','Jack'}
basketballSet={'John','Tom','Jack','Mary','Frank'}
s1=footballSet&basketballSet
s2=footballSet^basketballSet
print(“选择两个兴趣小组的学生有{},共{}人.format(s1,len(s1)}
print(“仅选一个兴趣小组的学生有{},共{}人.format(s2,len(s2)}
程序运行结果
选择两个兴趣小组的学生有{'Jack', 'Tom'},共2人
仅选一个兴趣小组的学生有{'Rose', 'John', 'Lily', 'Frank', 'Mary'},共5人
【试一试】 读程序,分析程序的运行结果
#E5-0.py
mto=["cc","bbbb","afa","sss","bbbb","cc",'shafa']
ato=list(set(mto))
print(ato)
ato.sort(key=mto.index) #按mto原索引顺序排序
print(ato)
运行结果
['bbbb', 'sss', 'cc', 'shafa', 'afa']
['cc', 'bbbb', 'afa', 'sss', 'shafa']
5.2 字典
字典
- 字典(dict)是以"{}"为界限符,以","分隔的键值对的集合。
- 字典的键值对之间无序。键相当于索引,它对应的值就是数据,通过键信息查找对应的值信息,这个过程叫映射
- 字典内的键必须是唯一(不可重复)的,值可以是任意数据类型,且值可以重复
- 字典中的键必须是不可变的数据类型,如整数、实数、字符串、元组等。不允许使用列表、集合、字典作为字典的键,因为这些类型的数据是可变的。
- 格式:
{<键1>:<值1>,<键2>:<值2>,……<键n>:<值n>}
>>> student={"190401301":"李佳原","190401302":"刘兴远","190401401":"张纯浩"}
>>> student
{'190401302': '刘兴远', '190401301': '李佳原', '190401401': '张纯浩'}
键值对之间没有顺序
字典与序列类型的区别
- 存取和访问数据的方式不同。序列类型通过编号存取数据,而字典是根据键存取。
- 序列类型是有序的数据集合,字典是无序的数据集合。字典中的键值对没有明确的顺序。
- 字典是可变类型,序列类型的字符串、元组是不可变类型,列表是可变类类型。
1 创建字典
【1】 创建字典并赋值
>>> d={ }#创建空字典
>>> print(d)
{}
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1
{'Tom': 20, 'Alice': 20, 'Mary': 19, 'Rose': 18}
>>> type(d) #返回d的数据类型
<class 'dict'>
>>> type(a1)
<class 'dict'>
【2】 用内建函数dict( )创建字典
>>>b1=dict( )#创建空字典
>>> b2
{}
>>> b2=dict(((1,"星期一"),(2,"星期二"),(3,"星期三"))) #以键值对形式的元组创建字典
>>> b2
{1: '星期一', 2: '星期二', 3: '星期三'}
>>> b3=dict([(1,"星期一"),(2,"星期二"),(3,"星期三")]) #以键值对形式的列表创建字典
>>> b3
{1: '星期一', 2: '星期二', 3: '星期三'}
>>> b4= dict(name='Allen', age=14, gender='male') #以"键=值"方式建立字典,但键必须是字符串型
>>> b4
{'gender': 'male', 'age': 14, 'name': 'Allen'}
【3】 用dict( )函数和zip( )函数创建字典
格式:
<字典名>=dict(zip(<序列1>,<序列2>))
用zip( )函数可以把两个序列(列表或元组)对应位置的元素做为一个键值对,生成一个字典
>>> d=dict(zip(["a","b","c"],[1,2,3]))
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> d2=dict(zip(("姓名","年龄","性别"),("王小华",20,"女")))
>>> d2
{'性别': '女', '年龄': 20, '姓名': '王小华'}
【4】 用内建函数fromkeys( )创建字典
格式:
dict.fromkeys(seq[,value])
{}. fromkeys(seq[,value])
适用于创建一个所有值都相等的字典
>>> c={}.fromkeys((1,2,3),"student") #指定所有键(1,2,3)对应的value值为"student"
>>> c
{1: 'student', 2: 'student', 3: 'student'}
>>> c=dict.fromkeys((1,2,3),"student")
>>> c
{1: 'student', 2: 'student', 3: 'student'}
>>> c=dict.fromkeys((1,2,3))#以给参数为键,但不指定value值,则创建value值为空的字典
>>> c
{1: None, 2: None, 3: None}
2 字典的基本操作
【1】 字典的访问
- 用下标访问字典中的元素,下标是字典中的"键"
- 格式:
字典名[键名]
或<值>=字典名[键名]
- 如果键在字典中,则返回该键对应的值,否则引发一个KeyError错误。
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1["Mary"]
19
>>> a1["Jack"]
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
a1["Jack"]
KeyError: 'Jack'
【2】 字典元素的添加与修改
- 字典没有预定义大小的限制,可以随时向字典添加新的键值对,或修改现有键 对应的值
- 格式:
字典名[键名]=<值>
- 若该键在字典中存在,是对该键对应的值进行修改(更新)操作,如果该键不在字典中,则表示添加一个新的"键值对",也就是字典中添加了一个新元素
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1["Mary"]=22
>>> a1
{'Alice': 20, 'Rose': 18, 'Tom': 20, 'Mary': 22}
>>> a1["Frank"]=42
>>> a1
{'Alice': 20, 'Rose': 18, 'Frank': 42, 'Tom': 20, 'Mary': 22}
【3】 字典的判断
- 用in或not in来判断某些键是否存在于字典中
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> "Tom" in a1
True
【4】 字典的长度
- 用len( )函数返回字典中键值对的数量
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> len(a1)
4
【5】 字典的删除
- 字典的删除用del命令实现,包括删除字典和字典中的元素
- 删除字典中的元素的命令为:
del 字典名[键名]
- 删除字典的命令为:
del 字典名
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> del a1["Mary"]
>>> a1
{'Alice': 20, 'Rose': 18, 'Tom': 20}
>>> del a1
>>> a1
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
a1
NameError: name 'a1' is not defined
2 字典的常用方法
- 格式:
<字典名>.<方法名>(<方法参数>)
操作方法 | 描述(以字典名是d为例) |
---|---|
d.keys() | 返回所有的键信息 |
d.values() | 返回所有的值信息 |
d.items() | 返回所有的键值对 |
d.get(key,default) | 键存在则返回相应值,否则返回默认值 |
d.pop(key,default) | 键存在则返回相应值,同时删除键值对,否则返回默认值 |
d.popitem() | 随机从字典取出一个键值对,以元组(key,value)形式返回 |
d.update(d1) | 将d1中所有键值添加到当前字典d中,并覆盖同名键的值 |
d.setdefault(key[,value]) | 如果字典中存在key,则返回key对应的值;若key不存在,则返回键值对key:value,同时把key:value添加到字典中,value的缺省值是None |
d.clear() | 删除所有的键值对,清空字典 |
【1】 d.keys() 、d.values()与d.items()
- 三个方法返回结果都是Python的一种内部数据类型 dict_keys,可以用list ( )、tuple( )函数将其转换为列表或元组
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.keys( )
dict_keys(['Alice', 'Rose', 'Tom', 'Mary'])
>>> list(a1.keys( ))#将字典的键转化为列表
['Alice', 'Rose', 'Tom', 'Mary']
>>> a1.values( )
dict_values([20, 18, 20, 19])
>>> tuple(a1.values( )) #将字典的值转化为元组
(20, 18, 20, 19)
>>> a1.items()
dict_items([('Alice', 20), ('Rose', 18), ('Tom', 20), ('Mary', 19)])
>>> list(a1.items( ))
[('Alice', 20), ('Rose', 18), ('Tom', 20), ('Mary', 19)]
【2】 d.get(key,default)
- 根据键信息查找并返回值信息,如果Key存在则返回相应值,否则返回默认值
- default可以省略,如果省略则默认值为空
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.get("Alice")
20
>>> a1.get("Frank")
>>> a1.get("Frank","查无此人")
'查无此人'
【3】 d.pop(key,default)
- 与get( )方法类似,根据键信息查找并返回值信息
- 不同的是 pop( )在取出相应值后,将从字典中删除对应的键值对
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.pop("Mary")
19
>>> a1
{'Alice': 20, 'Rose': 18, 'Tom': 20}
>>> a1.pop("Frank","查无此人")
'查无此人'
>>> a1
{'Alice': 20, 'Rose': 18, 'Tom': 20}
【4】 d.popitem( )
- 随机从字典中取出一个键值对,以元组(key,value)形式返回
- 取出后从字典中删除这个键值对
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.popitem()
('Alice', 20)
>>> a1
{'Rose': 18, 'Tom': 20, 'Mary': 19}
【5】 d.update(d1 )
- 将d1中所有键值添加到当前字典d中,并覆盖同名键的值
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a2={"John":28,"Mary":23}
>>> a1.update(a2)
>>> a1
{'Rose': 18, 'John': 28, 'Mary': 23, 'Alice': 20, 'Tom': 20}
【6】 d.clear( )
- 删除所有的键值对,清空字典
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.clear()
>>> a1
{}
【7】 d.setdefault(key[,value] )
- 如果字典中存在key,则返回key对应的值;
- 若key不存在,则返回键值对key:value,同时把key:value添加到字典中,value的缺省值是None
>>>a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
>>> a1.setdefault("Mary")
19
>>> a1.setdefault("Frank",20)
20
>>> a1
{'Tom': 20, 'Rose': 18, 'Alice': 20, 'Mary': 19, 'Frank': 20}
>>> a1.setdefault("Lily")
>>> a1
{'Tom': 20, 'Mary': 19, 'Frank': 20, 'Rose': 18, 'Alice': 20, 'Lily': None,}
3 字典的遍历
- 字典可以用for 循环对其元素进行遍历,其语法结构为:
for < 变量名> in <字典名>:
<语句块>
- for循环返回的变量名是字典的键,如果需要获得键对应的值,可以在语句块中通过get( )方法获得
a1={"Tom":20,"Mary":19,"Alice":20,"Rose":18}
for k in a1:
print("name:{} and age:{}".format(k,a1.get(k)))
运行结果
name:Alice and age:20
name:Rose and age:18
name:Tom and age:20
name:Mary and age:19
综合实例
【例5-2】 编写程序,将一个字典的键和值对调
分析:
- 对调就是将字典的键变为值,值变为键
- 遍历字典,得到原字典的键和值,将原来的键作为值,原来的值作为键名,采用
<字典名>[键名]=<值>
方式,逐个添加字典元素
#E5-2.py
a={"a":1,"b":2,"c":3}
b={}
for k in a:
b[a[k]]=k #或 b[a.get(k)]=k
print(b)
运行结果
{1: 'a', 2: 'b', 3: 'c'}
【例5-3】 编写程序,输入一串英文字符,单词之间用空格分隔开,统计其中单词出现的次数
分析:
- 可采用字典数据结构来实现
- 如果某个单出现在字典中,可以将单词(键)作为索引来访问它的值,并将它的关联值加1
- 如果某个单词(键)不在字典中,使用赋值的方式创建键,并将它的关键值设为1
#E5-3.py
string=input("请输入一段英文字符:")
strList=string.split()
wordDict={}
for word in strList:
if word in wordDict:
wordDict[word]+=1
else:
wordDict[word]=1
print(wordDict)
运行结果
请输入一段英文字符:to be or not to be
{'or': 1, 'not': 1, 'be': 2, 'to': 2}
【扩展 例5-3】 编写程序,输入一串英文字符,单词之间用空格分隔开,统计其中单词出现的次数,并按降序输出词频
#E5-3-2.py
string=input("请输入一段英文字符:")
strList=string.split()
wordDict={}
for word in strList:
if word in wordDict:
wordDict[word]+=1
else:
wordDict[word]=1
items=list(wordDict.items())
items.sort(key=lambda x:x[1],reverse=True)
for i in range(len(items)):
word,count=items[i]
print("{0:<10}{1:>5}".format(word,count))
运行结果
请输入一段英文字符:to be or not to be
to 2
be 2
or 1
not 1
课后思考
【 试一试】 已知有三位学生参加了主题演讲的记录列表:
names=["Tom","Jack","Mary","Tom","Lily","Jack","Rose"],请统计出每个学生参加活动的次数并记录到字典中,结果如下(顺序不做要求):
{'Tom': 2, 'Lily': 1, 'Mary': 1, 'Jack': 2, 'Rose': 1}
#E5-4.py
names=["Tom","Jack","Mary","Tom","Lily","Jack","Rose"]
names_dict={ }
for key in names:
if key not in names_dict:
names_dict[key]=1
else:
names_dict[key]+=1
print(names_dict)
【 试一试】 已知有三位学生参加了主题演讲的记录列表:
names=["Tom","Jack","Mary","Tom","Lily","Jack","Rose"],请统计出每个学生参加活动的次数,并按降序输出,结果如下:
Tom 2
Jack 2
Lily 1
Mary 1
Rose 1
#E5-5.py
names=["Tom","Jack","Mary","Tom","Lily","Jack","Rose"]
names_dict={ }
for key in names:
if key not in names_dict:
names_dict[key]=1
else:
names_dict[key]+=1
names_list=list(names_dict.items())
names_list.sort(key=lambda x:x[1],reverse=True)
for i in range(len(names_list)):
name,count=names_list[i]
print("{0:<10}{1:<5}".format(name,count))
【 试一试】 编写购物车程序,购物车类型为列表类型,列表的每个元素为一个字典类型,字典键值包括"name","price",编写程序实现如下功能:
(1)创建购物车:键盘输入商品信息(用空格隔开),并输出商品列表。例如输入:
电脑 3999
电视机 2980
冰箱 3289
洗衣机 2199
购物车列表为:
shoppingCart=[{"name":"电脑","price":3999}, {"name":"电视机","price":2980},
{"name":"冰箱","price":3289}, {"name":"洗衣机","price":2199}]
(2)从键盘输入用户资产(如3000),若购物车中商品总额大于用户资产,输出提示"您的余额不足!",否则输出提示"购买成功!"
(1)创建购物车:键盘输入商品信息(用空格隔开),并输出商品列表
#购物车程序
#E5-6.py
shoppingCart=[]
while True:
goodsDict={}
s=input(“请输入商品名称价格(空格分隔):”
if s==”exit”
break
else:
ls=s.split()
goodsDict[“name”]=ls[0]
goodsDict[“price”]=int(ls[1])
shoppingCart.append(goodsDict)
print(shoppingCart)
(2)从键盘输入账户余额(如3000),若购物车中商品总额大于账户余额,输出提示"您的余额不足!",否则输出提示"购买成功!"
#购物车程序
#E5-6.py
shoppingCart=[]
while True:
goodsDict={}
s=input(“请输入商品名称价格(空格分隔):”
if s==”exit”
break
else:
ls=s.split()
goodsDict[“name”]=ls[0]
goodsDict[“price”]=int(ls[1])
shoppingCart.append(goodsDict)
print(shoppingCart)
ye=int(input(“请输入账户余额:”)
goodsSum=0
for i in range(len(shoppingCart)):
goodsSum=goodsSum+shoppingCart[i][“price”]
if goodsSum>ye:
print(“您的余额不足!”)
else:
print(“购买成功!”)
【 试一试】 已知列表 aList=[14,89,23,65,78,39,98,41,11,87],将所有大于等于60的值保存至字典的关键字'>=60'对应的值(列表)中,将小于60的值保存至字典的关键字'<60'对应的值(列表)中,即{'>=60':大于等于60的所有值列表,'<60':小于60的所有值列表}。
程序的运行结果为:
{'<60': [14, 23, 39, 41, 11], '>=60': [89, 65, 78, 98, 87]}
#E5-7.py
aList=[14,89,23,65,78,39,98,41,11,87]
aDict={}
List1,List2=[],[]
for item in aList:
if item >=60:
List1.append(item)
aDict[“>=60”]=List1
else:
List2.append(item)
aDict[“<60”]=List2
print(aDict)
网友评论