什么是集合?正如其字面的意思,一堆东西集中合并到一起。乍一听貌似和容器没什么差别,嗯,好吧,集合也算是一种容器。
在学习这个容器有什么不同之前,先看看集合是如何创建的:
a = set() #可变集合 b = frozenset() #不可变集合 print a print b
集合分为两种,一种是不可变的,一种是可变的,两者的差异后面会分析。
不过,我们创建了两个空的集合貌似么什么意思。
为了使其有意义,我们就先来看集合最重要的功能:去重。
a = ('aaa',123,123,123) b = set(a) print b
可以看到元祖a中的重复的元素123在集合中只剩下一个了。所以,我们总结集合的概念:
集合就是将不同的元素放在一起组成一个集合对象。(不影响原来的对象)
此时,有机智的同学看到集合里面有个方括号,立马想到了列表,并试图用索引来取值:
a = ('aaa',123,123,123) b = set() print b[0]
然而并不可以。
因为集合是无序的,和字典一样。
那么是否我们可以将集合看作是一种特殊的字典,只不过没有键,所以不能通过键去取值而已。
某种意义上是可以的,不过要注意,集合分为可变集合和不可变集合两种,不可变的集合就不能像字典一样修改元素。
另外补充一点:
a = 'abcdaabbccdd' b = set(a) print b
因为字符串也是序列,所以也可以用来去重,但是一般没什么用就是。
那么,对字典去重会怎么样?我们在字典中了解到了字典会自动处理键名重复的问题,那么值能进行去重吗?
a = {'a':123,'b':123} b = set(a) print b
看来还是对键的去重,并没有什么用,除非要将所以的键组合成一个集合,其去重意义不大。看业务需要吧。
这里,我对去重的总结是:去除重复的引用,相信看过我在python序列中的说明的人能明白这是什么意思。
知道去重的本质之后,我们有这个需求,我有两个容器,我想得到这两个容器去重后的结果。
那我这样写:
a = ('scolia',123,456,666) b = ('scolia',666) c = set(a,b) print c
结果是大红字甩脸,说只要一个参数,结果给了两个。
好吧,首先看看其内部是怎么接受参数的:
首先,这里的__init__是构造函数,在类的创建时会讲。现在只要知道我们的参数是传给 seq=() 的,而按照这里的写法,应该是可以传一个元祖的。
那么是不是就可以这样写:
a = ('scolia',123,456,666) b = ('scolia',666) c = set((a,b)) print c
传是传进去了,但结果并不是我们想象的那样。
看来集合的去重是针对一个对象的,那么我们就可以将集合总结成:
集合是去除一个对象(序列或类序列的字典)中,元素的重复引用的。
所以我们想要实现这个需要,首先要将两个对象拼接起来:
a = ('scolia',123,456,666) b = ('scolia',666) c = set(a+b) print c
关于序列的拼接不只一种,详情看我之前的博文。
而不同类型的序列先要强制转换成一种,否则报错
a = ('scolia',123,456,666) b = ['scolia',666] c = set(a+tuple(b)) print c
下面我们来开始学习其内置方法吧。
老办法,先看看帮助文档。
Help on class set in module __builtin__: class set(object) | set() -> new empty set object | set(iterable) -> new set object | | Build an unordered collection of unique elements. | | Methods defined here: | | __and__(...) | x.__and__(y) <==> x&y | | __cmp__(...) | x.__cmp__(y) <==> cmp(x,y) | | __contains__(...) | x.__contains__(y) <==> y in x. | | __eq__(...) | x.__eq__(y) <==> x==y | | __ge__(...) | x.__ge__(y) <==> x>=y | | __getattribute__(...) | x.__getattribute__('name') <==> x.name | | __gt__(...) | x.__gt__(y) <==> x>y | | __iand__(...) | x.__iand__(y) <==> x&=y | | __init__(...) | x.__init__(...) initializes x; see help(type(x)) for signature | | __ior__(...) | x.__ior__(y) <==> x|=y | | __isub__(...) | x.__isub__(y) <==> x-=y | | __iter__(...) | x.__iter__() <==> iter(x) | | __ixor__(...) | x.__ixor__(y) <==> x^=y | | __le__(...) | x.__le__(y) <==> x<=y | | __len__(...) | x.__len__() <==> len(x) | | __lt__(...) | x.__lt__(y) <==> x<y | | __ne__(...) | x.__ne__(y) <==> x!=y | | __or__(...) | x.__or__(y) <==> x|y | | __rand__(...) | x.__rand__(y) <==> y&x | | __reduce__(...) | Return state information for pickling. | | __repr__(...) | x.__repr__() <==> repr(x) | | __ror__(...) | x.__ror__(y) <==> y|x | | __rsub__(...) | x.__rsub__(y) <==> y-x | | __rxor__(...) | x.__rxor__(y) <==> y^x | | __sizeof__(...) | S.__sizeof__() -> size of S in memory, in bytes | | __sub__(...) | x.__sub__(y) <==> x-y | | __xor__(...) | x.__xor__(y) <==> x^y | | add(...) | Add an element to a set. | | This has no effect if the element is already present. | | clear(...) | Remove all elements from this set. | | copy(...) | Return a shallow copy of a set. | | difference(...) | Return the difference of two or more sets as a new set. | | (i.e. all elements that are in this set but not the others.) | | difference_update(...) | Remove all elements of another set from this set. | | discard(...) | Remove an element from a set if it is a member. | | If the element is not a member, do nothing. | | intersection(...) | Return the intersection of two or more sets as a new set. | | (i.e. elements that are common to all of the sets.) | | intersection_update(...) | Update a set with the intersection of itself and another. | | isdisjoint(...) | Return True if two sets have a null intersection. | | issubset(...) | Report whether another set contains this set. | | issuperset(...) | Report whether this set contains another set. | | pop(...) | Remove and return an arbitrary set element. | Raises KeyError if the set is empty. | | remove(...) | Remove an element from a set; it must be a member. | | If the element is not a member, raise a KeyError. | | symmetric_difference(...) | Return the symmetric difference of two sets as a new set. | | (i.e. all elements that are in exactly one of the sets.) | | symmetric_difference_update(...) | Update a set with the symmetric difference of itself and another. | | union(...) | Return the union of sets as a new set. | | (i.e. all elements that are in either set.) | | update(...) | Update a set with the union of itself and others. | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __hash__ = None | | __new__ = <built-in method __new__ of type object> | T.__new__(S, ...) -> a new object with type S, a subtype of T
可分为以下几类:
1.运算符相关
3.内置函数相关(省略)
4.普通内置方法
1.运算符相关
不知道你是否还记得数学中的集合,就是那个交集、补集什么的,忘记了请自己重修。
下面用一个表格总结:
数学符号 | python符号 | 说明 |
∩ | & | 交集,如a&b |
∪ | | | 并集,如a|b |
- 或 | - | 差补或相对补集 |
△ | ^ | 对称差分 |
⊂ | < | 真子集 |
⊆ | <= | 子集 |
⊃ | > | 真超集 |
⊇ | >= | 超集 |
= | == | 等于,两个集合相等 |
≠ | != | 不等于 |
∈ | in | 属于,是里面的元素 |
∉ | not in | 不属于 |
这部分内容只能呼叫数学老师了。我就不讲了。
2.普通内置方法
虽说在帮助文档中列出了一堆方法,但集合是分为可变的和不可变的,所以有些方法,如修改操作只有可变的集合可以使用,所以内置方法又可以分为两种:
1.所有集合都能使用的:
方法 | 说明 |
a.issubset(b) | 如果a是b的子集,则返回True,否则返回False |
a.issuperset(b) | 如果a是b的超集,则返回True,否则返回False |
a.intersection(b) | 返回a和b的交集 |
a.union(b) | 返回a和b的并集 |
a.difference(b) | 返回一个新集合,该集合是集合a去除和b元素部分后的 |
a.symmetric_difference(b) | 返回一个新集合,该集合是a或b的成员,但不是a和b共有的成员 |
a.copy() | 返回一个浅拷贝。 |
2.可修改集合才能用的:
方法 | 说明 |
a.add() | 在集合里添加新的对象 |
a.clear() | 清空集合里的所有对象 |
a.pop() | 删除a中的任意元素,并返回,为空时报错 |
a.remove(obj) | 在a中删除obj这个元素,没找到时报错 |
a.discard(obj) | 在a中删除obj这个元素,没找到时什么都不做,返回None |
a.update(b) | 用b中的元素修改a,此时a包含a或b的成员。相当与合并 |
a.intersection_update(b) | 用a和b的交集更新a集合 |
a.difference_update(b) | 从a中移除和b一样的元素 |
a.symmetric_difference(b) | 将a修改成a和b的对称差分 |
这里交并补、子集超集之类的基本数学概念就不再重复了。这里讲下差补和对称差分:
1.差补
a =set( 'scolia') b = set('good') print a - b print a.difference(b)
实际上就是干掉了 a 中的 'o',而之所以干掉 'o' 是因为两个集合里面都有 'o'。
本想用数学公式来解释一番的,然而我的数学也已经遗忘到太平洋里去了。
2.对称差分
a =set( 'scolia') b = set('good') print a ^ b print a.symmetric_difference(b)
将干掉两种的交集,然后把剩下来的拿出去组成新集合。
好了,集合就先讲到这里了,这么多东西我也不一定全部记得住,要用的时候再来查就行了。
参考资料:戳这里