python数据结构(三)set使用和原理

1. set是什么?

数学上,把set称做由不同的元素组成的集合,集合(set)的成员通常被称做集合元素(set elements)。Python把这个概念引入到它的集合类型对象里。集合对象是一组无序排列的可哈希的值。集合关系测试和union、intersection等操作符在Python里也同样如我们所预想地那样工作。

2.set特点

集合的元素有三个特征:

1.确定性:集合中的元素必须是确定的;

2.互异性:集合中的元素互不相同,如:集合A={1,a},则a不能等于1);

3.无序性:集合中的元素没有先后之分,如:{3,4,5}和{3,5,4}算作同一个集合。

python中集合(set)是一个无序不重复元素的集,基本功能包括关系测试消除重复元素,还可以计算交集、差集、并集等,它与列表(list)的行为类似,区别在于set不同包括重复的值,而且set元素是无序的。

在python中可以用大括号 {} 创建集合。注意:如果要创建或初始化一个空集合,你必须用 set() 而不是 {} 。因为后者{} 作为创建一个空的字典,以后我们会介绍字典这种数据结构。

3.python集合种类

python集合有两种不同的类型:

可变集合(set):可变集合(set),可以添加和删除元素,

不可变集合(frozenset):不可变集合(frozenset)一旦创建就不允许更改。

根据上面两种集合可知,set是可变对象,因此既不能用做字典的键也不能做其他集合中的元素。frozenset则正好相反,它是不可变对象(这点类似python中的tuple),即它们有哈希值,能被用做字典的键或是作为集合中的一个成员。

注意: 上面我们说 set 是可变对象,不可哈希,是指创建的整个对象,而不是指对象中某个元素,这一点可以类比list和tuple区别。

4. 创建set

1.创建空集合

s1 = set()

2.创建可变集合

s1 = {2, 1, 3}

print(s1) # 下面输出结果看出,集合是无序的# {1, 2, 3}

3.创建不可变集合frozenset

s1 = frozenset('12aa')

print(s1)

# frozenset({'2', 'a', '1'})

【创建集合讨论】

根据上面代码,我们发现,创建空集合只能用set() ,不能用{} 。而且非空集合打印结果是由 {} 包裹起来的,前面我们学元组(tuple),它的打印结果是由 () 包裹起来的。另外有第二段代码可以看出集合是无序的,通过set() 可以把其他数据结构转换为集合,而且自动去重。

5. 集合遍历和访问

循环遍历:

# 集合遍历使用for

s1 = {5, 4, 3, 2, 1}

for x in s1:

    print(x, end=" ")

# 1 2 3 4 5

集合没有索引,不能使用索引获取对应元素,比如使用s[1] 会报错,想想为什么?

s1={1,2,3}

print(s1[1])

#    print(s1[1])

# TypeError: 'set' object does not support indexing

上面代码可以看到使用索引获取元素报错,根本原因是集合是无序的,不可hash。

6. 集合的交并补运算

数学符号 Python符号 含义

例子

s1 = {1, 2, 3, 4, 5}

s2 = {4, 5, 6, 7, 8}

print(s1 - s2)  # 差集

# {1, 2, 3}

print(s2 - s1)

# {8, 6, 7}

print(s1 & s2)  # 交集

# {4, 5}

print(s1 | s2)  # 并集

# {1, 2, 3, 4, 5, 6, 7, 8}

print(s1 ^ s2)  # 交叉补集

# {1, 2, 3, 6, 7, 8}

print(6 in s1)

# False

print(6 not in s1)

# True

7. 操作集合的函数

len(set):集合元素个数

max(set):返回集合元素最大值

min(set):返回集合元素最小值

list(set):将集合转换为列表

del:删除集合,释放内存空间

8. 集合类定义的函数

例子

s1 = {1, 2, 3}

s1.add(4)

s1.add(3)  # 添加重复元素,自动去重

print(s1)

# {1, 2, 3, 4}

s2 = {3, 4, 5}

s1.update(s2)

print(s1)

# {1, 2, 3, 4, 5}

s1.remove(1)

print(s1)

# {2, 3, 4, 5}

9. 集合各种操作时间复杂度

【附加阅读】

底层实现机制,面试常见问题

1. 集合底层数据结构

集合能如此高效,和它的内部的数据结构密不可分。不同于其他数据结构,集合的内部结构是一张哈希表:哈希表内只存储单一的元素。不了解哈希原理和特性的可网上搜索一下,以后我们也会写一些这方面内容。

2. 哈希表插入数据

当向集合中插入数据时,Python会根据通过 hash(valuse) 函数,计算该元素对应的哈希值。得到哈希值(例如为 hash)之后,再结合集合要存储数据的个数(例如 n),就可以得到该元素应该插入到哈希表中的位置(比如用 取模法 hash%n 方式)。

如果哈希表中此位置是空的,那么此元素就可以直接插入其中;反之,如果此位置已被其他元素占用,那么 Python 会比较这两个元素的哈希值是否相等:

重点:

--如果相等,则表明该元素已经存在,再比较他们的值,不相等就进行更新;

--如果不相等,这种情况称为哈希冲突(即两个元素的键不同,但求得的哈希值相同)。这种情况下,Python 会使用开放定址法、再哈希法等继续寻找哈希表中空余的位置,直到找到位置。

3. 哈希表查找数据

在哈希表中查找数据,和插入操作类似,Python 会根据哈希值,找到该元素应该存储到哈希表中的位置,然后和该位置的元素比较元素值:

如果相等,则证明找到;

反之,则证明当初存储该元素时,遇到了哈希冲突,需要继续使用当初解决哈希冲突的方法进行查找,直到找到该元素或者找到空位为止。 这里的找到空位,表示哈希表中没有存储目标元素。

4. 哈希表删除元素

对于删除操作,Python 会暂时对这个位置的元素赋于一个特殊的值,等到重新调整哈希表的大小时,再将其删除。

重点:

需要注意的是,哈希冲突的发生往往会降低字典和集合操作的速度

因此,为了保证其高效性,字典和集合内的哈希表,通常会保证其至少留有 1/3 的剩余空间。

随着元素的不停插入,当剩余空间小于 1/3 时,Python 会重新获取更大的内存空间,扩充哈希表,与此同时,表内所有的元素位置都会被重新排放。

虽然哈希冲突和哈希表大小的调整,都会导致速度减缓,但是这种情况发生的次数极少。所以,平均情况下,仍能保证插入、查找和删除的时间复杂度为 O(1)。

5. set 怎么判断两个元素是不是重复,怎么去重的?

--set的去重是通过两个函数__hash____eq__结合实现的。

--当两个元素的哈希值不相同时,就认为这两个变量是不同的

--当两个元素哈希值一样时,调用__eq__方法,当返回值为True时认为这两个变量是同一个,应该去除一个。返回FALSE时,不去重。


本文为CSDN博主「Mr番茄蛋」的原创文章,原文链接

https://blog.csdn.net/qq_35203425/article/details/100774387

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容