Python中的集合(Set)

在Python中,集合(Set) 是一个无序、不重复的序列,它不支持索引。

创建集合

一般在创建集合时,分为创建空集合和非空集合,其创建方式如下:

# 创建空集合
set1 = set()

# 创建同一数据类型元素的集合
set2 = {"a", "b", "c", "d", "e", "f"}

# 创建不同数据类型元素的集合
set3 = {"a", 2, False, ()}

从上面可以看到,我们只需要把集合的所有元素放在 大括号 {} 里面,每个元素之间通过 逗号 , 间隔起来即可,但需要注意的是,我们创建空集合是不能通过 {} 来创建,因为 {} 表示的是一个空字典。

当然,集合中同样允许存放不同数据类型的元素,但有一点比较特殊,集合中存放的元素必须是不可变对象,而在Python中 list、dict、set 都是可变对象,所以集合中不允许存放 list、dict、set 类型的元素,否则会出现报错。

>>> set1 = {1, [1, 2]}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>>
>>> set1 = {1, {"name": "wintest"}}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>>
>>> set1 = {1, {1, 2}}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

我们在集合中可以存放元组,假如我们在元组中存储有 list、dict、set 类型的对象,然后再把该元组作为一个元素存储到集合中,这样做是否可行呢?

答案是否定的。不管嵌套了多少层,只要集合元素中出现了可变对象,存储到集合时就会出现报错。

集合中元素不可重复

集合中是不允许出现重复元素的,当我们存储多个重复元素到集合中,集合就会自动去重,每个元素只保留一个。

>>> set1 = {1, 2, 1, 3, 4, 1, 5, 2, 3}
>>> set1
{1, 2, 3, 4, 5}
>>>
>>> set2 = {"a", "b", "c", "d", "a", "a", "c"}
>>> set2
{'a', 'd', 'b', 'c'}

集合中元素无序

有时候我们会有一种错觉,认为集合似乎是有序的,比如下面这个例子:

>>> set1 = {2, 6, 5, 4, 1, 3}
>>> set1
{1, 2, 3, 4, 5, 6}

从上面看起来,集合貌似自动进行了排序,但我们在集合中多放几个元素时,就能够明显感受到集合无序的特点,比如下面这个例子:

>>> set1 = {2, 6, 15, 141, 21, 31, 101, 7, 996}
>>> set1
{2, 996, 101, 6, 7, 141, 15, 21, 31}

当我们在使用到集合时,不应该假定其有顺序,即便其可能会有某种顺序,我们也应该把其当作无序进行使用。

添加集合元素

  • 通过 add() 添加元素

我们把一个元素添加到集合中,如果集合中已经存在该元素,那么集合不进行任何操作。

>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.add(5)
>>> set1
{1, 2, 3, 4, 5}
>>>
>>> set1.add(3)
>>> set1
{1, 2, 3, 4, 5}
  • 通过 update() 添加元素

我们通过 update() 添加元素时,参数必须是可迭代对象,比如可以是 str、list、tuple、set、dict 等类型,该方法不同于 add() 方法,add() 是把参数当作一个整体添加到集合中,而 update() 则是把参数里的所有元素逐一添加到集合中。

>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.update("ab")
>>> set1
{1, 2, 3, 4, 'a', 'b'}
>>>
>>> set1.update([11, 22])
>>> set1
{1, 2, 3, 4, 11, 'a', 22, 'b'}
>>>
>>> set1.update((33, (44, 55)))
>>> set1
{1, 2, 3, 4, 33, 11, 'a', 22, (44, 55), 'b'}

如果添加的元素在集合中已经存在,那么该元素只会出现一次,会忽略掉重复元素。

>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.update([11, 22], (22, 33))  # 添加中有重复元素
>>> set1
{1, 2, 3, 4, 33, 11, 22}
>>>

删除集合元素

  • 通过 remove() 删除指定元素,元素不存在则报错
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.remove(2)
>>> set1
{1, 3, 4}
>>>
>>> set1.remove(2)  # 元素不存在,会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 2
  • 通过 discard() 删除指定元素,元素不存在不会报错
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.discard(2)
>>> set1
{1, 3, 4}
>>>
>>> set1.discard(2)  # 元素不存在,并不会报错
>>> set1
{1, 3, 4}
  • 通过 pop() 随机删除元素,会返回删除的元素
>>> set1 = {2, 6, 15, 141, 21, 31, 101, 7, 996}
>>>
>>> set1.pop()
2
>>> set1.pop()
996
>>> set1.pop()
101
>>> set1.pop()
6
>>> set1.pop()
7
>>> set1
{141, 15, 21, 31}

如果集合为空时使用 pop() 方法,则会出现报错:

>>> set1 = set()
>>>
>>> set1.pop()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'pop from an empty set'
  • 通过 clear() 删除集合所有元素
>>> set1 = {1, 2, 3, 4}
>>>
>>> set1.clear()
>>>
>>> print(set1)
set()

集合运算操作符

  • 运算符 & ,取交集,返回2个集合中相同的元素
>>> set1 = {1, 2, 3, 4}
>>> set2 = {1, 5, 6, 4}
>>>
>>> set1 & set2
{1, 4}
  • 运算符 | ,取并集,合并2个集合并去除重复元素
>>> set1 = {1, 2, 3, 4}
>>> set2 = {1, 5, 6, 4}
>>>
>>> set1 | set2
{1, 2, 3, 4, 5, 6}
  • 运算符 - ,取差集,从集合中去除元素
>>> set1 = {1, 2, 3, 4}
>>> set2 = {1, 5, 6, 4}
>>>
>>> set1 - set2
{2, 3}
>>>
>>> set2 - set1
{5, 6}
  • 运算符 ^ ,取对称差集,返回两个集合中不重复的元素集合
>>> set1 = {1, 2, 3, 4}
>>> set2 = {1, 5, 6, 4}
>>>
>>> set1 ^ set2
{2, 3, 5, 6}
  • 关键字 in

通过关键字 in ,可检查当前集合中是否包含指定元素,返回结果为布尔值 True 或 False。

>>> set1 = {1, 2, 3, 4}
>>>
>>> print(2 in set1)
True
>>>
>>> print(6 in set1)
False

通过关键字 in ,还可以用于遍历当前集合。

books = {"语文", "数学", "英语", "历史", "物理", "化学"}
for i in books:
    print(i, end=" ")

集合常见函数&方法

函数 & 方法 描述
len(set) 返回集合元素个数
max(set) 返回集合元素最大值
min(set) 返回集合元素最小值
set(iterable) 将可迭代对象转换为集合,若 iterable 为空则创建空集合
set.add(obj) 给集合添加元素
set.update(obj) 给集合添加元素
set.remove(obj) 删除集合中指定元素,元素不存在会报错
set.discard(obj) 删除集合中指定元素,元素不存在不会报错
set.pop() 随机删除元素
set.clear() 清空集合中所有元素
set.copy() 拷贝一个集合,使用的是浅拷贝
set1.difference(set2) 返回多个集合的差集
set1.intersection(set2) 返回集合的交集
set1.isdisjoint(set2) 判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False
set1.issubset(set2) 判断指定集合是否为该方法参数集合的子集
set1.symmetric_difference(set2) 返回两个集合中不重复的元素集合
set1.union(set2) 返回两个集合的并集
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,208评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,502评论 3 405
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,496评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,176评论 1 302
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,185评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,630评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,992评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,973评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,510评论 1 325
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,546评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,659评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,250评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,990评论 3 340
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,421评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,569评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,238评论 3 382
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,732评论 2 366

推荐阅读更多精彩内容