2020年4月15日&16日 第五章 字典和集合

第五章 字典和集合

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)

>>> 

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)

强调

  • 若emps={ } 将创建一个字典,而非创建一个集合
  • 创建集合时,Python会自动消除重复的值
  • 以上创建的为可变集合
#(4)创建不可变集合
>>> set3=frozenset('hello world')
>>> set3
frozenset({'l', 'w', ' ', 'e', 'd', 'r', 'h', 'o'})
>>> type(set3)

>>> 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 判断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的数据类型

>>> type(a1)

【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 "", line 1, in 
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 "", line 1, in 
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)

你可能感兴趣的:(2020年4月15日&16日 第五章 字典和集合)