集合(set)

集合(set)是一个无序且元素不重复的集合,其基本功能包括关系测试和消除重复元素。集合使用大括号({})来表示元素,并使用逗号进行分隔。需要注意的是,如果要创建一个空集合,必须使用 set() 而不是 {},因为后者创建的是一个空字典。集合在形式上使用的是花括号,但与字典无关。

集合的核心特性是自动去重,这在很多情况下能够帮助我们省去很多麻烦。

>>> s = set([1,1,2,3,3,4])
>>> s
{1, 2, 3, 4}        # 自动去重
>>> set("it is a nice day")     # 对于字符串,集合会把它一个一个拆开,然后去重
{'s', 'e', 'y', 't', 'c', 'n', ' ', 'd', 'i', 'a'}

通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果:

>>> s = {1, 2, 3, 4}
>>> s
{1, 2, 3, 4}
>>> s.add(5)
>>> s
{1, 2, 3, 4, 5}
>>> s.add(5)
>>> s
{1, 2, 3, 4, 5}

可以通过update()方法,将另一个对象更新到已有的集合中,这一过程同样会进行去重。

>>> s
{1, 2, 3, 4, 5}
>>> s.update("hello")
>>> s
{1, 2, 3, 4, 5, 'e', 'o', 'l', 'h'}

通过remove(key)方法删除指定元素,或者使用pop()方法。注意,集合的pop方法无法设置参数,删除指定的元素:

>>> s
{1, 2, 3, 4, 5, 'e', 'o', 'l', 'h'}
>>> s.remove("l")
>>> s
{1, 2, 3, 4, 5, 'e', 'o', 'h'}
>>> s.pop()
1
>>> s
{2, 3, 4, 5, 'e', 'o', 'h'}
>>> s.pop(3)
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    s.pop(3)
TypeError: pop() takes no arguments (1 given)

说了这么多,有没有同学注意到,我没有从集合取某个元素。为什么呢?因为集合既不支持下标索引也不支持字典那样的通过键获取值。

那么集合支持哪些操作呢?全在这里:

>>> dir(set)
['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']

除了add、clear、copy、pop、remove、update等集合常规操作,剩下的全是数学意义上的集合操作,交并差等等。

对集合进行交并差等,既可以使用union一类的英文方法名,也可以更方便的使用减号表示差集,“&”表示交集,“|”表示并集。看看下面的例子:

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # 删除重复的
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # 检测成员
True
>>> 'crabgrass' in basket
False
>>> # 以下演示了两个集合的交、并、差操作
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # a 中唯一的字母
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # 在 a 中的字母,但不在 b 中
{'r', 'd', 'b'}
>>> a | b                              # 在 a 或 b 中的字母
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # 在 a 和 b 中都有的字母
{'a', 'c'}
>>> a ^ b                              # 在 a 或 b 中的字母,但不同时在 a 和 b 中
{'r', 'd', 'b', 'm', 'z', 'l'}

集合是Python内置的数据类型之一,但在很多书籍中往往不被重视甚至被忽略。实际上,集合是一种非常有用的数据结构,它具备去重和集合运算等其他内置类型所不具备的功能,在很多场合有着非常重要的作用,比如在网络爬虫中。

网络爬虫需要发散链接,不断爬取所有的超级链接才能把整个站点爬取下来。然而,在成千上万个页面链接中,很大一部分可能是重复的链接或者循环互链,如果不对链接进行去重处理,那么爬虫就可能陷入死循环或者出现错误。

这个时候可以用集合的去重功能,保留一个不重复的元素集合,每当爬取一个新链接时,可以在集合中查看是否已经存在,如果不存在则可以开始爬取,并将链接加入集合中,否则就忽略当前链接。使用集合比使用列表或者字典要更高效、更节省空间。

标签: python, python下载, Python教程, Python技术, Python学习, Python学习教程, Python语言, Python开发, Python入门教程, Python进阶教程, Python高级教程, Python面试题, Python笔试题, Python编程思想