14.python中的集合

  什么是集合?正如其字面的意思,一堆东西集中合并到一起。乍一听貌似和容器没什么差别,嗯,好吧,集合也算是一种容器。

  在学习这个容器有什么不同之前,先看看集合是如何创建的:

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
set

  可分为以下几类:

  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)

  

  将干掉两种的交集,然后把剩下来的拿出去组成新集合。

  


 好了,集合就先讲到这里了,这么多东西我也不一定全部记得住,要用的时候再来查就行了。

参考资料:戳这里

原文地址:https://www.cnblogs.com/scolia/p/5540453.html