通常我们对集合的定义是"把一定范围的,确定的,可以区别的事物当作一个整体来看待",集合中的各个事物通常称为集合的元素,集合应该满足以下特性:
- 无序性:一个集合中,每个元素的地位都是相通的,元素之间是无序的
- 互异性:一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次
- 确定性:给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居其一,不允许有模棱两可的情况出现
创建集合
创建集合可以使用{}字面量语法,{}中需要至少有一个元素,因为没有元素的{}并不是空集合,而是一个空字典。也可以使用内置函数set来创建一个集合,准确的说set并不是一个函数,而是创建集合对象的构造器。set也可以将其他序列转成集合,例如:set('hello')会得到一个包含了4个字符的集合(重复的l会被去掉)
集合的运算
set1 = {1, 2, 3, 4, 5}
set2 = {2, 4, 6, 8}
# 成员运算 - 确定性(元素要么在集合中,要么不在集合中)
# 集合的成员运算在效率上是远远高于列表的成员运算
print(1 in set1) # True
print(1 not in set1) # False
# 交集
print(set1 & set2) # {2, 4}
print(set1.intersection(set2)) # {2, 4}
# 并集
print(set1 | set2) # {1, 2, 3, 4, 5, 6, 8}
print(set1.union(set2)) # {1, 2, 3, 4, 5, 6, 8}
#差集
print(set1 - set2) # {1, 3, 5}
print(set1.difference(set2)) # {1, 3, 5}
print(set2 - set1) # {8, 6}
# 对称差
print(set1 ^ set2) # {1, 3, 5, 6, 8}
print((set1 | set2) - (set1 & set2)) # {1, 3, 5, 6, 8}
print(set1.symmetric_difference(set2)) # {1, 3, 5, 6, 8}
集合的操作
集合底层使用的是哈希存储,通过计算元素的哈希码来决定元素存储的位置,这是一种高效率的存储方案
哈希存储的关键是设计一个好的哈希函数,尽量保证不同的对象能够计算出不同的哈希码
可变容器(列表,集合,字典)都无法计算哈希码,因此都不能放到集合中,作为集合的元素
set1 = {'apple', 'banana', 'pitaya', 'apple'}
# 集合中可以放元组,因为元组是不可变的
set2 = {(1, 2, 3), (4, 5, 6)}
# 添加元素
set1.add('grape')
print(set1) # {'pitaya', 'apple', 'grape', 'banana'}
# 删除元素 - discard删除已知元素,pop是随机删除一个元素
set1.discard('pitaya')
print(set1.pop()) # grape
print(set1) # {'banana', 'apple'}
# 清空元素
set1.clear()
print(set1) # set()
# 列表可以转为集合,然后在转回列表(去重)
nums = [1, 2, 1, 10, 10, 10, 5, 3, 9, 9]
set3 = set(nums)
print(set1) # {1, 2, 3, 5, 9, 10}
list1 = list(set3)
print(list1) # [1, 2, 3, 5, 9, 10]
# 列表可以转为元组
tuple1 = tuple(list1)
print(tuple1) # (1, 2, 3, 5, 9, 10)
set4 = set('hello')
print(set4) # {'e', 'l', 'o', 'h'}
不可变集合
Python中还有一种不可变的集合,名字叫frozenset,set和rozenset的区别就如同list(列表)和tuple(元组)的区别,frozenset由于是不可变类型,能够计算出哈希码,因此它可以作为set中的元素。除了不能添加和删除元素,frozenset在其他方面和set基本一样
set1 = frozenset({1, 3, 5, 7})
set2 = frozenset(range(1, 6))
print(set1 & set2) # frozenset({1, 3, 5})
print(set1 | set2) # frozenset({1, 2, 3, 4, 5, 7})
print(set1 - set2) # frozenset({7})
print(set2 < set2) # False