Python学习的第十一天
集合
哈希
- 如果一个对象无法计算哈希码,就不能放入集合中,可变容器(列表、集合、字典)都不能放入集合中
- 集合底层使用了一种高效的存储方式:哈希存储(散列存储),因此集合在元素查找时效率远高于列表,不依赖问题的规模,是一种常量级时间复杂度的存储方案
- 列表不是可以哈希的类型
- 列表元组字符串的存储方式为顺序存储,优点为可以实现随机存取,缺点为需要判断元素是否存在,查找元素的效率十分低下
- 哈希冲突会使效率降低
- 百度网盘极速秒传原理:没有真正上传,其服务器已经拥有该文件,通过本地计算哈希码,上传哈希码后经过对比,返回数据:该用户已经拥有此文件并更改文件名
集合的性质
-
互异性,集合内没有重复的元素
-
无序性,集合内元素的顺序由哈希码决定,每个元素的地位都是相同的,元素之间是无序的,因此不能支持索引运算
-
确定性,一个元素,只有属于和不属于集合两种情况,没有其他模棱两可的情况
-
集合的类型为set
例:
# 输入的字符串被随机排列,且删除了重复元素 set5 = set('hello') print(set5) # bool值同样满足集合的互异性 set2 = {True, False, True, True, False} print(set2) # 集合可以储存元组 set3 = {(1, 2, 3), (4, 5, 6)} print(set3) # 列表可以储存集合 list4 = [set1, set2] print(list4)
集合的创建
集合可以由{}的字面量语法创建,其中至少由一个元素,如果没有元素,将不是空集合而是空字典
集合也可以由内置函数set创建,通过这种方法可以创建空列表
集合中的元素一定是hashable类型,即不可变类型,可以计算哈希码的类型
例:
#创建集合的字面量语法(重复元素不会出现在集合中)
set1 = {1, 2, 3, 3, 3, 2}
print(set1) # {1, 2, 3}
print(len(set1)) # 3
# 创建集合的构造器语法(后面会讲到什么是构造器)
set2 = set('hello')
print(set2) # {'h', 'l', 'o', 'e'}
# 将列表转换成集合(可以去掉列表中的重复元素)
set3 = set([1, 2, 3, 3, 2, 1])
print(set3) # {1, 2, 3}
# 创建集合的生成式语法(将列表生成式的[]换成{})
set4 = {num for num in range(1, 20) if num % 3 == 0 or num % 5 == 0}
print(set4) # {3, 5, 6, 9, 10, 12, 15, 18}
# 集合元素的循环遍历
for elem in set4:
print(elem)
集合的运算
-
集合的成员运算
set1 = {1, 2, 3, 4, 5} set2 = {2, 4, 6, 8} print(1 in set1) print(1 not in set1)
-
集合的交并差运算
set1 = {1, 2, 3, 4, 5} set2 = {2, 4, 6, 8} # 交集 # 符号方法 print(set1 & set2) # 内置函数方法 print(set1.intersection(set2)) # 并集 # 符号方法 print(set1 | set2) # 内置函数方法 print(set1.union(set2)) # 差集 # 差集不满足交换律 # 符号方法 print(set1 - set2) # 内置函数方法 print(set1.difference(set2)) # 符号方法 print(set2 - set1) # 内置函数方法 print(set2.difference(set1)) # 对称差 # 对称差满足交换律 # 符号方法 print(set1 ^ set2) # 定义方法 print((set1 | set2) - (set1 & set2)) # 内置函数方法 print(set1.symmetric_difference(set2)) set3 = {1, 2, 3, 4, 5, 6, 7, 8, 9} # 判断真子集 # 符号方法 print(set1 < set3) # 内置函数方法 print(set1.issubset(set3)) # 判断子集 print(set1 <= set3) # 判断超集 # 符号方法 print(set3 > set2) # 内置函数方法 print(set3.issuperset(set2))
集合的相关操作
set1 = {'apple', 'banana', 'pitaya', 'apple'}
# 添加元素
# 由于集合的无序性,不可以使用追加(append)和插入(insert),加入后元素的位置不确定
set1.add('grape')
set1.add('durian')
print(set1)
# 删除元素
# 删除指定元素
set1.discard('pitaya')
# 随机删除元素,但会返回删除的值
print(set1.pop())
print(set1.pop())
print(set1)
# 清空元素
set1.clear()
print(set1)
# 集合、元组和列表之间可以相互转换
nums = [1, 1, 10, 10, 10, 5, 3, 9, 9]
# 列表转换为集合
set2 = set(nums)
print(set2)
# 集合转换为列表
list3 = list(set2)
print(list3)
# 列表转换为元组
tuple4 = tuple(list3)
print(tuple4)