文章目录
定义
可变集合
集合(set)是一个无序的不重复元素序列。可以使用大括号 { } 或者 set() 函数创建集合。
创建空集合时只能使用set(),因为{}会被当作字典
# 使用set创建集合
>>> s=set([1,'asd','qwe','zxc','asd'])
>>> s
{1, 'zxc', 'qwe', 'asd'}
# 使用{}创建集合
>>> s={1,'asd','qwe','zxc','asd'}
>>> s
{1, 'zxc', 'qwe', 'asd'}
#集合是无序的
>>> s={1,'asd','qwe','zxc','asd'}
>>> s[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable
在创建集合的时候,如果发现重复的元素,则会过滤掉,最终结果时无序的不重复元素序列。
不可变集合
还有一种集合不能原地修改,这种集合的创建方法是用
frozenset(),顾名思义,这是一个被“冻结”的集合,当然是不能修改的,这种集合就是hashable类型——可哈希。
>>> f= frozenset('qwe')
# 不可修改
>>> f.add('asd')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'frozenset' object has no attribute 'add'
操作
unhashable
以set()创立的集合都是可原地修改的集合,或者说是可变的,也可以说是unhashable。
在创建的集合中包含集合,列表,字典时会有以下报错:
>>> a=set([[],[],[]])
TypeError: unhashable type: 'list'
>>> a=set([{},{},{}])
TypeError: unhashable type: 'dict'
>>> a=set([set(),set(),set()])
TypeError: unhashable type: 'set'
认真阅读报错信息,有这样的词汇:“unhashable”,在理解这个词之前,先看它的反义词“hashable”,很多时候翻译为“可哈希”,其实它有一个不是音译的名词“散列”。如果我们简单点理解,某数据“不可哈希”(unhashable)就是其可变,如列表,字典和集合都能原地修改,就是unhashable。否则,不可变的,类似字符串那样不能原地修改的就是hashable(可哈希)。
**对于字典类型的对象,其”键“必须是hashable,即不可变。**所以键不能为列表。
现在遇到的集合,其元素也是“可哈希”的。上面的例子,试图将字典、列表和集合作为元素的元素,就报错了。而且报错信息中明确告知列表,字典和集合是不可哈希类型,言外之意,里面的元素都应该是可哈希类型。
hashable
由于通过frozenset创建的不可变集合是可哈希的,所以其创建的集合就能够作为set创建集合的元素:
>>> set([frozenset('asd'),frozenset('wqe')])
{frozenset({'z', 'c', 'x'}), frozenset({'e', 'q', 'w'})}
set() 和list()
我们可以通过set()将列表转化为集合,通过list()将集合转化为列表。
>>> s={1,'asd','qwe','zxc','asd'}
>>> l=list(s)
>>> l
[1, 'zxc', 'qwe', 'asd']
>>> set(l)
{1, 'zxc', 'qwe', 'asd'}
集合的函数
add和update
add是添加一个元素到集合
>>> s
{1, 'zxc', 'qwe', 'asd'}
>>> s.add('en')
>>> s
{1, 'zxc', 'qwe', 'en', 'asd'}
update是添加一个集合到另一个集合(如果是字符串,则被差分为集合)
>>> s={1,'asd','qwe','zxc'}
>>> s.update('sd')
>>> s
{1, 'zxc', 'qwe', 'asd', 's', 'd'}
>>> d={1,3,'df'}
>>> s.update(d)
>>> s
{1, 'zxc', 3, 'qwe', 'df', 'asd', 's', 'd'}
len
len判断集合内元素个数
>>> s=set(['a','sd',1,'asw'])
>>> len(s)
4
pop,remove,discard,clear
pop随意删除一个,并返回该值。空则报错
{1, 'zxc', 3, 'qwe', 'df', 'asd', 's', 'd'}
>>> s.pop()
1
>>> s
{'zxc', 3, 'qwe', 'df', 'asd', 's', 'd'}
== remove==删除指定元素,如果删除的该元素不存在则报错
>>> s.remove(3)
>>> s.remove('sd')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'sd'
>>> s
{'zxc', 'qwe', 'df', 'asd', 's', 'd'}
discard与remove类似,删除指定元素,如果删除元素不存在则什么都不做
>>> s.discard('zxc')
>>> s.discard('sd')
>>> s
{'qwe', 'df', 'asd', 's', 'd'}
clear删除集合中所有的元素
>>> s.clear()
>>> s
set()
集合运算
等价/不等价
>>> a=set(['as','qw','asd',2])
>>> b=set(['s','qww','dsd',2])
>>> a==b
False
>>> a!=b
True
子集/超集
判断集合A是否是集合B的子集,可以使用A<B,返回True则是子集,否则不是。另外,还可以使用函数A.issubset(B)判断。
>>> b=set(['s','qww','dsd',2])
>>> a=set(['s','asd',2])
>>> a<b
False
>>> a.issubset(b)
False
>>> a=set(['s','dsd',2])
>>> a<b
True
>>> a.issubset(b)
True
并集/交集/补
>>> a=set(['s','dsd',2])
>>> b=set(['s',1,'sd'])
# 并集
>>> a|b
{'sd', 1, 2, 'dsd', 's'}
>>> a.union(b)
{'sd', 1, 2, 'dsd', 's'}
# 交集
>>> a&b
{'s'}
>>> a.intersection(b)
{'s'}
# 补集
>>> a-b
{2, 'dsd'}
>>> a.difference(b)
{2, 'dsd'}