第040讲:集合(下)
知识点回顾:0. 本节视频
https://www.bilibili.com/video/BV1c4411e77t?p=41
1. 冻结的集合
Python 将集合细分为可变和不可变两种对象,前者是 set(),后者是 frozenset():
>>> t = frozenset("FishC")
>>> t
frozenset({'s', 'C', 'i', 'F', 'h'})
被冻结的集合(frozenset())是不支持修改的。
如果我们尝试修改它,那么可怕的事情就会发生:
>>> t.update(, "23")
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
t.update(, "23")
AttributeError: 'frozenset' object has no attribute 'update'
2. 仅适用于 set() 对象的方法
update(*others) 方法使用 others 容器中的元素来更新集合:
>>> s = set("FishC")
>>> s
{'s', 'C', 'i', 'F', 'h'}
>>> s.update(, "23")
>>> s
{'s', 1, 'C', 'i', 'F', 'h', '3', '2'}
intersection_update(*others)、difference_update(*others) 和 symmetric_difference_update(other) 分别是使用前面讲过的交集、差集和对称差集的方式来更新集合:
>>> s.intersection_update("FishC")
>>> s
{'s', 'C', 'i', 'F', 'h'}
>>> s.difference_update("Php", "Python")
>>> s
{'s', 'C', 'i', 'F'}
>>> s.symmetric_difference_update("Python")
>>> s
{'s', 't', 'C', 'o', 'h', 'i', 'y', 'F', 'n', 'P'}
如果希望要单纯地往集合里添加数据,可以使用 add(elem) 方法:
>>> s.add("45")
>>> s
{'s', 't', 'C', 'o', 'h', 'i', 'y', 'F', '45', 'n', 'P'}
在集合中删除某个元素,可以使用 remove(elem) 或者 discard(elem) 方法:
>>> s.remove("瓦迈")
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
s.remove("瓦迈")
KeyError: '瓦迈'
>>> s.discard("瓦迈")
删除还有一个 pop() 方法,用于随机从集合中弹出一个元素:
>>> s.pop()
's'
>>> s.pop()
't'
>>> s.pop()
'C'
>>> s
{'o', 'h', 'i', 'y', 'F', '45', 'n', 'P'}
最后,clear() 方法就是将集合清空:
>>> s.clear()
>>> s
set()
3. 可哈希
想要正确地创建字典和集合,是有一个刚性需求的 —— 那就是字典的键,还有集合的元素,它们都必须是可哈希的。
如果一个对象是可哈希的,那么就要求它的哈希值必须在其整个程序的生命周期中都保持不变。
通过 hash() 函数,可以轻松获取一个对象的哈希值:
>>> hash(1)
1
>>> hash(1.0)
1
>>> hash(1.001)
2305843009213441
这个哈希值有什么用呢?
对于我们来说可能没啥用,但对于字典和集合来说,却是 “木之根,水之源”,这里我们就不再展开论述了,再深挖下去就有点越俎代庖的感觉了……
有兴趣的童鞋可以看看这一篇扩展阅读 -> Python字典的实现原理
Python 中大多数不可变对象是可哈希的,而那些可变的容器则不哈希:
>>> hash("FishC")
2090433017907150752
>>> hash()
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
hash()
TypeError: unhashable type: 'list'
如果我们把列表换成元组,元组是不可变的对象,那就应该是可哈希的:
>>> hash((1, 2, 3))
529344067295497451
前面我们说了,只有可哈希的对象,才有资格作为字典的键,以及集合的元素:
>>> {"Python":520, "FishC":1314}
{'Python': 520, 'FishC': 1314}
>>> {"Python", "FishC", 520, 1314}
{520, 1314, 'Python', 'FishC'}
4. 嵌套的集合
如果要实现一个嵌套的集合,可不可行?
>>> x = {1, 2, 3}
>>> y = {x, 4, 5}
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
y = {x, 4, 5}
TypeError: unhashable type: 'set'
这样写是不行的,因为集合它是一个可变的容器,而可变的容器则是不可哈希。
那我们非要将集合嵌套,还有没有办法?
有!
没错,使用 “冰山美人” frozenset() 对象:
>>> x = frozenset(x)
>>> y = {x, 4, 5}
>>> y
{frozenset({1, 2, 3}), 4, 5}
5. 本节思维导图
6. 快问快答
本节课配套的「快问快答」已发布,快来看看自己能拿多少分吧 -> 传送门
7. 温馨提示
如果在学习本节课的过程中遇到问题,可以在这个帖子下方提问哦~
集合分为可变集合与不可变集合。上节介绍的方法不会对集合内容进行改动,适用于所有集合;本节介绍的方法会对集合内容进行改动,故仅适用于可变集合。其中,add()方法是将传入的字符串整体作为一个元素插入集合中,与update()等方法迭代获取传入字符串中的每一个字符进行处理有所不同;remove()方法与discard()方法的区别在于当指定的元素不存在时,前者会抛出KeyError异常,后者则不会抛出异常。
后半节讲解了“可哈希”的概念,即某个对象的哈希值(可通过内置函数hash()来获取)在其整个程序的生命周期中保持不变。Python中大多数不可变对象都是可哈希的,而可变对象则是不可哈希的,这有点类似于Python对象的唯一标识值id,增量赋值后可变序列的id值不改变,不可变序列的id值会改变!字典的键和集合的元素都必须是可哈希的,故不能为可变对象;字典和集合本身是可变对象,不可哈希,故不可直接实现嵌套,但使用不可变集合却可以实现嵌套!
本节最后还讲了一个“奇技淫巧”——将列表转换成集合可以大幅提升程序的执行效率,因为集合的背后有散列表的支持,而列表则没有;换句话说,列表的每次查找都需要从头到尾地扫描,而集合则只需要简单的查表操作。以空间换时间,这也正是字典和集合高效背后的玄机! >>> ['frozenset()对象是不可变的']
['frozenset()对象是不可变的']
>>> t = frozenset('FishC')
>>> t
frozenset({'C', 'i', 's', 'F', 'h'})
>>> s = set('FishC')
>>> s
{'C', 'i', 's', 'F', 'h'}
>>> s.update(,'23')
>>> s
{1, 'C', '3', 'i', '2', 's', 'F', 'h'}
>>> t.update(,'23')
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
t.update(,'23')
AttributeError: 'frozenset' object has no attribute 'update'
>>> s.intersection_update('FishC')
>>> s
{'C', 'i', 's', 'F', 'h'}
>>> s.difference_update('Php','Python')
>>> s
{'C', 'i', 's', 'F'}
>>> s.symmetric_difference_update('Python')
>>> s
{'t', 'C', 'P', 'h', 'i', 'n', 'y', 's', 'F', 'o'}
>>> ['上节课讲到的 没有update, 他们只是返回计算结果,而加上update 之后,是对集合进行更新']
['上节课讲到的 没有update, 他们只是返回计算结果,而加上update 之后,是对集合进行更新']
>>> ['s.update()即是 s.unionupdate(),即是合并集合']
['s.update()即是 s.unionupdate(),即是合并集合']
>>> s.add('45')
>>> s
{'t', 'C', '45', 'P', 'h', 'i', 'n', 'y', 's', 'F', 'o'}
>>> ['add() 方法与 update() 方法不同,前者是将整个字符串当作一个元素插入集合,而后者是将字符串 分开呈一个个元素后再插入集合']
['add() 方法与 update() 方法不同,前者是将整个字符串当作一个元素插入集合,而后者是将字符串 分开呈一个个元素后再插入集合']
>>> s.remove('晚买')
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
s.remove('晚买')
KeyError: '晚买'
>>> s.discard('晚买')
>>> s
{'t', 'C', '45', 'P', 'h', 'i', 'n', 'y', 's', 'F', 'o'}
>>> s.pop()
't'
>>> s.pop()
'C'
>>> s.pop()
'45'
>>> s.pop()
'P'
>>> s
{'h', 'i', 'n', 'y', 's', 'F', 'o'}
>>> s.clear()
>>> s
set()
>>> ['集合元素的删除,可以使用 remove() 方法和 discard() 方法,两者的区别是,如果要删除的元素原集合中没有,那么前者就会报错,而后者会静默处理; pop() 方法是随机剔除集合中的一个元素;clear() 则是将一个集合变为一个空集合']
['集合元素的删除,可以使用 remove() 方法和 discard() 方法,两者的区别是,如果要删除的元素原集合中没有,那么前者就会报错,而后者会静默处理; pop() 方法是随机剔除集合中的一个元素;clear() 则是将一个集合变为一个空集合']
>>> ['通过 hash() 函数可以获得一个对象的 哈希 值']
['通过 hash() 函数可以获得一个对象的 哈希 值']
>>> hash(1)
1
>>> hash(1.0)
1
>>> hash(1.001)
2305843009213441
>>> ['整数的 哈希 值是整数,两个相同值的哈希 值是相同的']
['整数的 哈希 值是整数,两个相同值的哈希 值是相同的']
>>> ['Python 中 大多不可变的对象都是 可哈希 的,而可变的对象都是 不可哈希 的,可哈希 就是其哈希值是不变的']
['Python 中 大多不可变的对象都是 可哈希 的,而可变的对象都是 不可哈希 的,可哈希 就是其哈希值是不变的']
>>> hash('FishC')
-5249203814098794668
>>> hash()
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
hash()
TypeError: unhashable type: 'list'
>>> ['如上所示:字符串是不可变的,其有哈希值,而列表是可变的,因此其没有哈希值']
['如上所示:字符串是不可变的,其有哈希值,而列表是可变的,因此其没有哈希值']
>>> hash((1,2,3))
529344067295497451
>>> {'Python':520,'FishC':1314}
{'Python': 520, 'FishC': 1314}
>>> {:'FishC'}
Traceback (most recent call last):
File "<pyshell#41>", line 1, in <module>
{:'FishC'}
TypeError: unhashable type: 'list'
>>> ['可哈希的对象才可以作为 键,因此上述不可哈希的列表不能作为字典的键']
['可哈希的对象才可以作为 键,因此上述不可哈希的列表不能作为字典的键']
>>> {'Python','FishC',520,1314}
{520, 1314, 'FishC', 'Python'}
>>> {'Python','FishC',520,1314,}
Traceback (most recent call last):
File "<pyshell#44>", line 1, in <module>
{'Python','FishC',520,1314,}
TypeError: unhashable type: 'list'
>>> x = {1,2,3}
>>> y = {x,4,5}
Traceback (most recent call last):
File "<pyshell#46>", line 1, in <module>
y = {x,4,5}
TypeError: unhashable type: 'set'
>>> ['上述嵌套集合中 x 是可变的,因此不能作为 键']
['上述嵌套集合中 x 是可变的,因此不能作为 键']
>>> x = frozenset(x)
>>> y = {x,4,5}
>>> y
{frozenset({1, 2, 3}), 4, 5}
>>> 阿西吧什么时候我是一个成功过的人呢 打卡 小甲鱼真的很用心,谢谢你啊
卡打
已经迷糊了
滴滴滴~打卡{:10_298:} Learning... 打卡 集合分为可变集合和不可变集合,set() 为一般集合,frozenset() 是不可变集合,对集合做变动操作是对于可变集合来说,add() 方法是将传入的字符串整体作为一个元素插入集合中,与update() 等方法迭代获取字符串的每一位字节处理不同;remove() 方法与 discard() 方法的区别在于指定的元素不存在时 ,前者会抛出 KeyError 异常,后者则不会抛出异常。哈希即:某个对象的哈希值(可通过内置函数hash() 来获取),在其整给程序的生命周期中保持不变,python 中大多数不可变对象都是可哈希的,而不可变对象都是不可哈希的,同时将列表转换成集合能够大幅度提升程序的执行效率,因为集合的背后有散列表的支持,而列表则没有,换句话,列表的每次查询都是从头到尾的扫描,而集合则只需要简单的查表操作。 打卡 继续坚持学习但好像前面学习过的又忘记了 集合(下)
1. 冻结的集合
>>> t = frozenset("FishC")
>>> t
frozenset({'s', 'C', 'i', 'F', 'h'})
2.适用于set()对象的方法
update(*others) 方法使用 others 容器中的元素来更新集合
>>> s = set("FishC")
>>> s
{'s', 'C', 'i', 'F', 'h'}
>>> s.update(, "23")
>>> s
{'s', 1, 'C', 'i', 'F', 'h', '3', '2'}
intersection_update(*others) 交集
s.intersection_update("FishC")
>>> s
{'s', 'C', 'i', 'F', 'h'}
difference_update(*others) 差集
s.difference_update("Php", "Python")
>>> s
{'s', 'C', 'i', 'F'}
symmetric_difference_update(other) 对称差集
s.symmetric_difference_update("Python")
>>> s
{'s', 't', 'C', 'o', 'h', 'i', 'y', 'F', 'n', 'P'}
add()方法 添加一个数据
>>> s.add("45")
>>> s
{'s', 't', 'C', 'o', 'h', 'i', 'y', 'F', '45', 'n', 'P'}
删除数据
remove(elem) 指定字符
s.remove("瓦迈")
discard(elem) 静默删除
s.discard("瓦迈")
pop() 方法 用于随机从集合中弹出一个元素
>>> s.pop()
's'
>>> s.pop()
't'
>>> s.pop()
'C'
>>> s
{'o', 'h', 'i', 'y', 'F', '45', 'n', 'P'}
clear() 方法 将集合清空
>>> s.clear()
>>> s
set()
可哈希
hash() 函数 轻松获取一个对象的哈希值
>>> hash(1)
1
>>> hash(1.0)
1
>>> hash(1.001)
2305843009213441
嵌套的集合
不可变集合 “冰山美人” frozenset() 对象
>>> x = frozenset(x)
>>> y = {x, 4, 5}
>>> y
{frozenset({1, 2, 3}), 4, 5}
一周过去了才学个二十集我真的会谢 本帖最后由 xiaohongchen 于 2023-9-12 17:37 编辑
{:5_108:} 有点迷糊了。 好多内容,好好学习-20250529 仅适用于可变集合的方法
t = frozenset("FishC")
t
frozenset({'h', 'C', 'F', 's', 'i'})
s = set("FishC")
s
{'h', 'C', 'F', 's', 'i'}
s.update(, "23")
s
{'h', 'C', 1, '3', 'F', 's', 'i', '2'}--- update加入的字符串,会按照单个字符追加到集合里面。
s.intersection_update("FishC")
s
{'C', 'F', 'i', 's', 'h'}
s.difference_update("Php", "Python")
s
{'C', 'F', 'i', 's'}
s.symmetric_difference_update("Python")
s
{'C', 't', 'o', 'F', 'i', 'y', 'P', 'n', 's', 'h'}
s.add("45")
s
{'C', 't', 'o', 'F', 'i', 'y', 'P', 'n', 's', '45', 'h'} ---add加入的字符串,会按照一个整体追加到集合里面。
s.remove("45")
s
{'C', 't', 'o', 'F', 'i', 'y', 'P', 'n', 's', 'h'}
s.discard("P")
s
{'C', 't', 'o', 'F', 'i', 'y', 'n', 's', 'h'}
s.remove("88")
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
s.remove("88")
KeyError: '88'
s.discard("88")
s.pop()
'C'
s.pop()
't'
s.pop()
'o'
s
{'F', 'i', 'y', 'n', 's', 'h'}
s.clear()
s
set()
哈希 hash
hash(1)
1
hash(1.0)
1
hash(1.001)
2305843009213441
hash("FishC")
7618438666111293819
hash()
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
hash()
TypeError: unhashable type: 'list'
hash((1, 2, 3))
529344067295497451
x = {1, 2, 3}
y = {x, 4, 5}
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
y = {x, 4, 5}
TypeError: cannot use 'set' as a set element (unhashable type: 'set')
x = frozenset(x)
y = {x, 4, 5}
y
{frozenset({1, 2, 3}), 4, 5}---使用frozenset(),可以做嵌套集合
页:
[1]