Python.第五章(字典与集合)

字典与集合 

# 第五章 字典与集合

# 创建字典

# {键:值 ...}
# 键具有唯一性,是不可变类型,所以不能用列表作为键,一般用字符串,数字或者元组
# 一般需要多个元素充当键的时候 用 元组
dicGDP = {'2022年':1210207.2,'2021年':1149237.0}
print(dicGDP)
# {'2022年': 1210207.2, '2021年': 1149237.0}

# 内置函数dict()创建

# 类型1
year = ('2022年','2021年')
GDP = (1210207.2,1149237.0)
# zip()函数将两个等长的序列打扮成若干个双元素元组组成的zip对象
# zip(year,GDP)
dicGDP1 = dict(zip(year,GDP))
print(dicGDP1)
# {'2022年': 1210207.2, '2021年': 1149237.0}

# 类型2
item = [('2022年',1210207.2),('2021年',1149237.0)]
dicGDP2 = dict(item)
print(dicGDP2)
# {'2022年': 1210207.2, '2021年': 1149237.0}


# 访问字典

# 字典名[键]
print(dicGDP['2022年']) # 1210207.2

# 如果字典的值是个序列,可以进一步通过索引访问序列中的子元素
dicGDP3 = {'2022年': [1210207.2,141217.5], '2021年': [1149237.0,141236]}
print(dicGDP3['2021年']) # [1149237.0, 141236]
print(dicGDP3['2022年'][1]) # 141217.5


# dicGDP = {}  #创建空字典


# 添加条目


# 字典名[键] = 值
dicGDP['2020年'] = 1013567.0
print(dicGDP)
# {'2022年': 1210207.2, '2021年': 1149237.0, '2020年': 1013567.0}

# 修改条目
# 字典名[键] = 值
dicGDP['2022年'] = 888888
print(dicGDP)
# {'2022年': 888888, '2021年': 1149237.0, '2020年': 1013567.0}

# 如果修改的键不存在,则执行的是添加条目
dicGDP['2023年'] = 999999
print(dicGDP)
# {'2022年': 888888, '2021年': 1149237.0, '2020年': 1013567.0, '2023年': 999999}


# 删除字典条目

# 用del命令
# del 字典名[键]

del dicGDP['2023年']
print(dicGDP)
# {'2022年': 888888, '2021年': 1149237.0, '2020年': 1013567.0}

# 用pop()方法删除指定条目,必须指定不能缺省
# 字典名.pop(键,默认值)
# 与之前列表的类似会返回被删除值,可以用一个变量去接住它

dicGDP.pop('2022年')
print(dicGDP)
# {'2021年': 1149237.0, '2020年': 1013567.0}
# 当键不存在时要加默认值,否则会报错
d = dicGDP.pop('2024年','找不到要删除的条目')
print(dicGDP)
# {'2021年': 1149237.0, '2020年': 1013567.0}
print(d)
# 找不到要删除的条目

# popitem()方法 随机 删除字典条目,不能指定
# 字典名.popitem()
dicGDP1.popitem()
print(dicGDP1)
# {'2022年': 1210207.2}

# 用clear()清空字典条目,可以一次性清空,留下空字典
# 字典名.clear()
dicGDP2.clear()
print(dicGDP2) # {}

# 直接删除整个字典
# del 字典名
del dicGDP2

# 查找字典条目

# 成员运算符
# 键 in 字典
a = '2022年' in dicGDP3
print(a) # True

# 用get()方法获取条目的值
# 字典名.get(键,默认值)
c = dicGDP.get('2020年')
print(c)
# 1013567.0

# 如果指定的键不存在,又缺省默认值,系统会执行语句但不会返回任何值
print(dicGDP3)
# {'2022年': [1210207.2, 141217.5], '2021年': [1149237.0, 141236]}
b = dicGDP3.get('2023年','未知')
print(b) # 未知


# 例5-1 统计英文句子“Life is short,we need Python.”中各字符出现的次数

# 用字典来统计
# python中大小写字母不一样,所以要先转化为小写字母统一一下,那么就要用到字符串
s = 'Life is short,we need Python.'
s1 = s.lower()
counts = {}  # 建个空字典

# 法1
for c in s1:  # 遍历字符串中的每一个包括空格和句点
    if c in counts:  # 先判断在不在字典counts,如果不在说明时第一次出现,赋值为1,如果在出现过了,在原来的基础上+1
        counts[c] = counts[c] + 1
    else:
        counts[c] = 1
print(counts)

# 法2
# 简化法1,从第一个遍历,用get()获取,因为最开始是空字典,字符串中第一次出现的字典里肯定没有,那就把默认值赋为0
# 然后第一次出现在0的基础上+1
for c in s1:
    counts[c] = counts.get(c,0) + 1
print(counts)


# 字典的遍历

# keys() 遍历键
# values() 遍历值
# items() 遍历条目

# 结合for语句

# 遍历键
for k in dicGDP.keys():
    print(k)
# 2021年
# 2020年

# 遍历值
for v in dicGDP.values():
    print(v)
# 1149237.0
# 1013567.0

# 遍历条目
for item in dicGDP.items():
    print(item)
# ('2021年', 1149237.0)
# ('2020年', 1013567.0)

# 遍历条目 更推荐这种,方便操作
for (k,v) in dicGDP.items():  # (k,v) 或者 k,v 写法都可以
    print(k,v)
# 2021年 1149237.0
# 2020年 1013567.0


# 字典的排序

# 用sorted()函数
# sorted()函数将字典的 键 排序并以 列表 的形式返回
z = {'2014年':10, '2004年':0, '2024年':20}
z1 = sorted(z,reverse=True)  # 按降序排列
print(z1)
# ['2024年', '2014年', '2004年']

# 例5-2 按年份以升序和降序输出对应的值
z = {'2014年':10, '2004年':0, '2024年':20}
z1 = sorted(z,reverse=True)  # 按降序排列
for i in z1:  # 遍历列表z1=['2024年', '2014年', '2004年']
    print(i,z[i])
# 2024年 20
# 2014年 10
# 2004年 0

z1 = sorted(z,reverse=False)  # 或者写成sorted(z) # 按升序排列
for i in z1:  # 遍历列表z1=['2004年', '2014年', '2024年']
    print(i,z[i])
# 2004年 0
# 2014年 10
# 2024年 20

# 例5-3 按照 键:年份 的值 以升序和降序排列

# 可以先用列表生成式把字典转化为列表
# 对新列表进行排序

# 降序
lsVK = [(v,k) for (k,v) in z.items()]
# print(lsVK)  # [(10, '2014年'), (0, '2004年'), (20, '2024年')]
ls1 = sorted(lsVK,reverse=True)  # 降序
# print(ls1) # [(20, '2024年'), (10, '2014年'), (0, '2004年')]
lsKV = [(k,v) for (v,k) in ls1]
print(lsKV)  # [('2024年', 20), ('2014年', 10), ('2004年', 0)]

# 升序
lsVK = [(v,k) for (k,v) in z.items()]
# print(lsVK)  # [(10, '2014年'), (0, '2004年'), (20, '2024年')]
ls1 = sorted(lsVK,reverse=False)  # 升序
# print(ls1) # [(0, '2004年'), (10, '2014年'), (20, '2024年')]
lsKV = [(k,v) for (v,k) in ls1]
print(lsKV)  # [('2004年', 0), ('2014年', 10), ('2024年', 20)]


# 字典转换为列表的方法:

# items = list(dic.items())
# 这将返回一个包含元组的列表,每个元组的第一个元素是键,第二个元素是值
# 例如 dic = {'one': 1, 'two': 2, 'three': 3}
# 那么 list(dic.items()) 将返回 
# [('one', 1), ('two', 2), ('three', 3)]
# 字典的合并


# 用for循环
z = {'2014年':10, '2004年':0, '2024年':20}
zo = {'2012年':12, '2002年':2, '2022年':22}
# 把z加到zo后面
for (k,v) in z.items():
    zo[k] = v
print(z)  # {'2014年': 10, '2004年': 0, '2024年': 20}
print(zo)  # {'2012年': 12, '2002年': 2, '2022年': 22, '2014年': 10, '2004年': 0, '2024年': 20}

# 用update()方法
# 字典名.update(参数字典名)
# 把后面字典加到前面字典

z.update(zo)
print(z)  # {'2014年': 10, '2004年': 0, '2024年': 20, '2012年': 12, '2002年': 2, '2022年': 22}
print(zo)  # {'2012年':12, '2002年':2, '2022年':22}
zo.update(z)
print(zo)  # {'2012年': 12, '2002年': 2, '2022年': 22, '2014年': 10, '2004年': 0, '2024年': 20}
print(z)  # {'2014年':10, '2004年':0, '2024年':20}


# 用dict()函数
# 不仅可以创建字典(将一组双元素序列转换为字典),还可以将两个字典合并

z = {'2014年':10, '2004年':0, '2024年':20}
zo = {'2012年':12, '2002年':2, '2022年':22}
z1 = dict(z,**zo)
print(z1)  # {'2014年': 10, '2004年': 0, '2024年': 20, '2012年': 12, '2002年': 2, '2022年': 22}
print(z)  # {'2014年': 10, '2004年': 0, '2024年': 20}
print(zo)  # {'2012年': 12, '2002年': 2, '2022年': 22}


# 例5-4 将以下两个字典合并
# z = {'2014年':10, '2004年':0, '2024年':20}
# z2 = {'2014年':'马', '2004年':'猴', '2024年':'龙'}

# 分析 他们共用 相同的 键,并没有增加新的条目,仅仅只是将 值 合并
# 可以设置一个新的字典

z = {'2014年':10, '2004年':0, '2024年':20}
z2 = {'2014年':'马', '2004年':'猴', '2024年':'龙'}

zn = {}
for k in z.keys():
    zn[k] = (z[k],z2[k])  # 等价 zn[k] = z[k],z2[k] 默认 多个子元素 为元组
print(zn)
# 直接打印字典
# {'2014年': (10, '马'), '2004年': (0, '猴'), '2024年': (20, '龙')}

# for k in z.keys():
#     zn[k] = [z[k],z2[k]]  # 用[]把 值 设为 列表
# print(zn)  # {'2014年': [10, '马'], '2004年': [0, '猴'], '2024年': [20, '龙']}

# 一个一个输出
for item in zn.items():
    print(item)
# ('2014年', (10, '马'))
# ('2004年', (0, '猴'))
# ('2024年', (20, '龙'))


# 集合

# 集合里的元素是不可变的,所以不能用列表
# 集合的元素是无序的
# 集合里的元素是互异的,集合会自动去重

# 创建集合

# 直接创建
set1 = {1,3,8,3,6,5,7,7,9}
print(type(set1))  # <class 'set'>
print(set1)  # {1, 3, 5, 6, 7, 8, 9}   而且还自动排了序

# 用set()函数
set2 = set('I love China!')
print(set2)  # {'n', 'a', 'i', 'v', 'h', 'C', '!', 'e', 'l', 'I', ' ', 'o'}
set3 = set([7,7,5,9,3,2,2,0])
print(set3)  # {0, 2, 3, 5, 7, 9}

# 创建空集合
s1 = set()
print(type(s1))  # <class 'set'>


# 集合的访问

# 通过集合名做整体输出
# 通过for循环实现遍历

# 例5-5 生成20个0~20的随机数并输出其中互不相同的数
from random import *
ls = []
for i in range(21):
    ls.append(randint(0,20))
print('生成20个0~20的随机数为:')
print(ls)
# [18, 0, 17, 5, 4, 15, 10, 15, 8, 0, 16, 9, 3, 3, 20, 15, 18, 18, 18, 13, 12]
print('其中出现的数(即去重后的数):')
s = set(ls)
print(s)
# {0, 3, 4, 5, 8, 9, 10, 12, 13, 15, 16, 17, 18, 20}


# 集合的基本操作

# 与字典类似

# 添加元素
# S.add(item)  只能一个一个元素添加
# 将参数 item 作为元素添加到集合 S 中,如果item 是序列,则将其作为一个元素整体加入集合
# *作为参数的item只能是不可变的数据
S = {1,2,3}
S.add(4)
print(S)
# {1, 2, 3, 4}

S.add((5,7,2,5,3,1))
print(S)
# {1, 2, 3, 4, (5, 7, 2, 5, 3, 1)}

# S.update(items)
# 将参数序列items中的元素拆分去重后加入集合
# *参数items可以是可变数据
S1 = {1,2,3}
S1.update([2,3,4])
print(S1)  # {1, 2, 3, 4}
S1.update({2,2,2,5,9,1})
print(S1)  # {1, 2, 3, 4, 5, 9}


# 删除元素
# S.remove(item)
# 将指定元素 item 从集合 S中删除
# 如果元素 item 在集合中不存在,系统将报错
S = {1,2,3,4}
S.remove(3)
print(S)  # {1, 2, 4}

# S.discard(item)
# 将指定元素 item 从集合 S 中删除
# 如果 item在集合中不存在,系统正常执行,无任何输出
S = {1,2,3,4}
S.discard(1)
print(S)  # {2, 3, 4}

# S.pop()
# 从集合S中 随机 删除并返回一个元素
S = {11,21,30,45,57,62}
a = S.pop()
print(a,S)  # 21 {62, 57, 11, 45, 30}

# S.clear()
# 清空集合中所有的元素
S = {1,2,3,4}
S.clear()
print(S)  # set()


# 成员判断
# item in S
# 判断元素 item 是否在集合 S 中
# 若在,返回 True;若不在,则返回False
# 可配合remove()函数使用避免系统报错

S = {1,2,3,4}
if 5 in S:
    S.remove(5)


# 集合的数学运算

A = {1,2,3,4,5}
B = {4,5,6,7,8}

# 求并集
print(A|B)
# {1, 2, 3, 4, 5, 6, 7, 8}

print(A.union(B))
# {1, 2, 3, 4, 5, 6, 7, 8}
print(B.union(A))
# {1, 2, 3, 4, 5, 6, 7, 8}

# 求交集
print(A & B)
# {4, 5}
print(A.intersection(B))
# {4, 5}
print(B.intersection(A))
# {4, 5}

# 求差集
print(A-B)
# {1, 2, 3}
print(A.difference(B))
# {1, 2, 3}
print(B-A)
# {8, 6, 7}
print(B.difference(A))
# {8, 6, 7}

# 求对称差集
print(A^B)
# {1, 2, 3, 6, 7, 8}
print(A.symmetric_difference(B))
# {1, 2, 3, 6, 7, 8}
print(B.symmetric_difference(A))
# {1, 2, 3, 6, 7, 8}

# 例5-6 IEEE和TIOBE是两大热门编程语言排行榜。截上2018年12月
# IEEE榜排名前五的编程语言分别是: Python、C++、C、Java、C#
# TIOBE榜排名前五的编程语言是: Java、C、Python、C++、VB.NET
# 请编写程序求出:
# 上榜的所有语言  (去重)
# 在两个榜单同时进前五的语言  (求交集)
# 只在IEEE榜排进前五的语言  (求IEEE的差集)
# 只在一个榜单进前五的语言  (求对称差集)

IEEE = {'Python','C++','C','Java','C#'}
TIOBE = {'Java','C','Python','C++','VB.NET'}

print('上榜的所有语言:')  # (求并集)(包含有去重)
print(IEEE | TIOBE)
# {'Python', 'C++', 'VB.NET', 'C#', 'Java', 'C'}

print('在两个榜单同时进前五的语言:')  # (求交集)
print(IEEE & TIOBE)
# {'Python', 'Java', 'C++', 'C'}

print('只在IEEE榜排进前五的语言:')  # (求IEEE的差集)
print(IEEE - TIOBE)
# {'C#'}

print('只在一个榜单进前五的语言:')  # (分别求两个榜的差集)
print(IEEE ^ TIOBE)
# {'VB.NET', 'C#'}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值