脚本专栏 
首页 > 脚本专栏 > 浏览文章

跟老齐学Python之集合(set)

(编辑:jimmy 日期: 2024/11/30 浏览:3 次 )

回顾一下已经了解的数据类型:int/str/bool/list/dict/tuple

还真的不少了.

不过,python是一个发展的语言,没准以后还出别的呢.看官可能有疑问了,出了这么多的数据类型,我也记不住呀,特别是里面还有不少方法.

不要担心记不住,你只要记住爱因斯坦说的就好了.

爱因斯坦在美国演讲,有人问:“你可记得声音的速度是多少?你如何记下许多东西?”
爱因斯坦轻松答道:“声音的速度是多少,我必须查辞典才能回答。因为我从来不记在辞典上已经印着的东西,我的记忆力是用来记忆书本上没有的东西。”

多么霸气的回答,这回答不仅仅霸气,更是在告诉我们一种方法:只要能够通过某种方法查找到的,就不需要记忆.

那么,上面那么多数据类型的各种方法,都不需要记忆了,因为它们都可以通过下述方法但不限于这些方法查到(这句话的逻辑还是比较严密的,包括但不限于...)

交互模式下用dir()或者help()
google(不推荐Xdu,原因自己体会啦)

为了能够在总体上对已经学习过的数据类型有了解,我们不妨做如下分类:

1.是否为序列类型:即该数据的元素是否能够索引.其中序列类型的包括str/list/tuple
2.是否可以原处修改:即该数据的元素是否能够原处修改(特别提醒看官,这里说的是原处修改问题,有的资料里面说str不能修改,也是指原处修改问题.为了避免误解,特别强调了原处).能够原处修改的是list/dict(特别说明,dict的键必须是不可修改的,dict的值可原处修改)
什么原处修改"htmlcode">

> s1 = set("qiwsir") #把str中的字符拆解开,形成set.特别注意观察:qiwsir中有两个i
> s1         #但是在s1中,只有一个i,也就是不能重复
set(['q', 'i', 's', 'r', 'w'])

> s2 = set([123,"google","face","book","facebook","book"])  #通过list创建set.不能有重复,元素可以是int/str
> s2
set(['facebook', 123, 'google', 'book', 'face'])        #元素顺序排列不是按照指定顺序

> s3 = {"facebook",123}    #通过{}直接创建
> s3
set([123, 'facebook'])

再大胆做几个探究,请看官注意观察结果:

> s3 = {"facebook",[1,2,'a'],{"name":"python","lang":"english"},123}
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

> s3 = {"facebook",[1,2],123}
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

从上述实验中,可以看出,通过{}无法创建含有list/dict元素的set.

继续探索一个情况:

> s1
set(['q', 'i', 's', 'r', 'w'])
> s1[1] = "I"
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support item assignment

> s1   
set(['q', 'i', 's', 'r', 'w'])
> lst = list(s1)
> lst
['q', 'i', 's', 'r', 'w']
> lst[1] = "I"
> lst
['q', 'I', 's', 'r', 'w']

上面的探索中,将set和list做了一个对比,虽然说两者都能够做原处修改,但是,通过索引编号(偏移量)的方式,直接修改,list允许,但是set报错.

那么,set如何修改呢"htmlcode">

> dir(set)
['__and__', '__class__', '__cmp__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__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', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update'

然后用help()可以找到每个函数的具体使用方法,下面列几个例子:

增加元素

> help(set.add)

Help on method_descriptor:

add(...)
Add an element to a set. 
This has no effect if the element is already present.

下面在交互模式这个最好的实验室里面做实验:

> a_set = {}       #我想当然地认为这样也可以建立一个set
> a_set.add("qiwsir")   #报错.看看错误信息,居然告诉我dict没有add.我分明建立的是set呀.
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'add'
> type(a_set)       #type之后发现,计算机认为我建立的是一个dict   
<type 'dict'>

特别说明一下,{}这个东西,在dict和set中都用.但是,如上面的方法建立的是dict,不是set.这是python规定的.要建立set,只能用前面介绍的方法了.

> a_set = {'a','i'}    #这回就是set了吧
> type(a_set)
 <type 'set'>       #果然

> a_set.add("qiwsir")   #增加一个元素
> a_set          #原处修改,即原来的a_set引用对象已经改变
set(['i', 'a', 'qiwsir'])

> b_set = set("python")
> type(b_set)
<type 'set'>
> b_set
set(['h', 'o', 'n', 'p', 't', 'y'])
> b_set.add("qiwsir")
> b_set
set(['h', 'o', 'n', 'p', 't', 'qiwsir', 'y'])

> b_set.add([1,2,3])   #这样做是不行滴,跟前面一样,报错.
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

> b_set.add('[1,2,3]')  #可以这样!
> b_set
set(['[1,2,3]', 'h', 'o', 'n', 'p', 't', 'qiwsir', 'y'])

除了上面的增加元素方法之外,还能够从另外一个set中合并过来元素,方法是set.update(s2)

> help(set.update)
update(...)
  Update a set with the union of itself and others.

> s1
set(['a', 'b'])
> s2
set(['github', 'qiwsir'])
> s1.update(s2)    #把s2的元素并入到s1中.
> s1         #s1的引用对象修改
set(['a', 'qiwsir', 'b', 'github'])
> s2         #s2的未变
set(['github', 'qiwsir'])

删除

> help(set.pop)
pop(...)
  Remove and return an arbitrary set element.
  Raises KeyError if the set is empty.

> b_set
set(['[1,2,3]', 'h', 'o', 'n', 'p', 't', 'qiwsir', 'y'])
> b_set.pop()   #从set中任意选一个删除,并返回该值
'[1,2,3]'
> b_set.pop()
'h'
> b_set.pop()
'o'
> b_set
set(['n', 'p', 't', 'qiwsir', 'y'])

> b_set.pop("n") #如果要指定删除某个元素,报错了.
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: pop() takes no arguments (1 given)

set.pop()是从set中任意选一个元素,删除并将这个值返回.但是,不能指定删除某个元素.报错信息中就告诉我们了,pop()不能有参数.此外,如果set是空的了,也报错.这条是帮助信息告诉我们的,看官可以试试.

要删除指定的元素,怎么办"htmlcode">

> help(set.remove)

remove(...)
  Remove an element from a set; it must be a member.  

  If the element is not a member, raise a KeyError.
set.remove(obj)中的obj,必须是set中的元素,否则就报错.试一试:

> a_set
set(['i', 'a', 'qiwsir'])
> a_set.remove("i")
> a_set
set(['a', 'qiwsir'])
> a_set.remove("w")
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'w'

跟remove(obj)类似的还有一个discard(obj):

> help(set.discard)

discard(...)
    Remove an element from a set if it is a member.

    If the element is not a member, do nothing.
与help(set.remove)的信息对比,看看有什么不同.discard(obj)中的obj如果是set中的元素,就删除,如果不是,就什么也不做,do nothing.新闻就要对比着看才有意思呢.这里也一样.

> a_set.discard('a')
> a_set    
set(['qiwsir'])
> a_set.discard('b')
>

在删除上还有一个绝杀,就是set.clear(),它的功能是:Remove all elements from this set.(看官自己在交互模式下help(set.clear))

> a_set
set(['qiwsir'])
> a_set.clear()
> a_set
set([])
> bool(a_set)   #空了,bool一下返回False.
False

知识

集合,也是一个数学概念(以下定义来自维基百科)

集合(或简称集)是基本的数学概念,它是集合论的研究对象。最简单的说法,即是在最原始的集合论─朴素集合论─中的定义,集合就是“一堆东西”。集合里的“东西”,叫作元素。若然 x 是集合 A 的元素,记作 x ∈ A。

集合是现代数学中一个重要的基本概念。集合论的基本理论直到十九世纪末才被创立,现在已经是数学教育中一个普遍存在的部分,在小学时就开始学习了。这里对被数学家们称为“直观的”或“朴素的”集合论进行一个简短而基本的介绍;更详细的分析可见朴素集合论。对集合进行严格的公理推导可见公理化集合论。

在计算机中,集合是什么呢"htmlcode">

在计算机科学中,集合是一组可变数量的数据项(也可能是0个)的组合,这些数据项可能共享某些特征,需要以某种操作方式一起进行操作。一般来讲,这些数据项的类型是相同的,或基类相同(若使用的语言支持继承)。列表(或数组)通常不被认为是集合,因为其大小固定,但事实上它常常在实现中作为某些形式的集合使用。
集合的种类包括列表,集,多重集,树和图。枚举类型可以是列表或集。

不管是否明白,貌似很厉害呀.

是的,所以本讲仅仅是对集合有一个入门.关于集合的更多操作如运算/比较等,还没有涉及呢.

上一篇:Python中的类学习笔记
下一篇:Python函数嵌套实例
一句话新闻
微软与英特尔等合作伙伴联合定义“AI PC”:键盘需配有Copilot物理按键
几个月来,英特尔、微软、AMD和其它厂商都在共同推动“AI PC”的想法,朝着更多的AI功能迈进。在近日,英特尔在台北举行的开发者活动中,也宣布了关于AI PC加速计划、新的PC开发者计划和独立硬件供应商计划。
在此次发布会上,英特尔还发布了全新的全新的酷睿Ultra Meteor Lake NUC开发套件,以及联合微软等合作伙伴联合定义“AI PC”的定义标准。
友情链接:杰晶网络 DDR爱好者之家 南强小屋 黑松山资源网 白云城资源网 网站地图 SiteMap