Skip to content

Commit cdd1e4c

Browse files
committed
Fix style
1 parent 3417344 commit cdd1e4c

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

objects/set-object.md

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
#### python集合
1+
# python集合
22

33
set是无序且不重复的集合,是可变的,通常用来从列表中删除重复项以及计算数学运算,如交集、并集、差分和对称差分等集合操作。set 支持 x in set, len(set),和 for x in set。作为一个无序的集合,set不记录元素位置或者插入点。因此,sets不支持 indexing, 或其它类序列的操作。
44

5-
#### python集合概述
5+
## python集合概述
66

77
在set中,对应的set的值的存储是通过结构setentry来保存数据值的;
88

9-
```
9+
源文件:[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L26)
1010

11+
```
1112
typedef struct {
1213
PyObject *key;
1314
Py_hash_t hash; /* Cached hash code of the key */
@@ -16,6 +17,8 @@ typedef struct {
1617

1718
key就是保存的数据,hash就是保存的数据的hash,便于查找,set也是基于hash表来实现。对应的setentry所对应的set的数据结构如下;
1819

20+
源文件:[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L42)
21+
1922
```
2023
2124
typedef struct {
@@ -48,7 +51,7 @@ typedef struct {
4851

4952
![内存图片](./python_set.png)
5053

51-
#### python集合(set)示例
54+
## python集合(set)示例
5255

5356
示例脚本如下:
5457

@@ -115,10 +118,12 @@ python -m dis set_test.py
115118

116119
通过该字节码指令可知,创建set调用了BUILD_SET指令,初始化完成之后,就调用set的add方法添加元素,调用remove删除元素,调用update来更新集合,通过union来合并集合。接下来就详细分析一下相关的操作流程。
117120

118-
##### set的创建与初始化
121+
## set的创建与初始化
119122

120123
查找BUILD_SET的虚拟机执行函数如下;
121124

125+
源文件:[Python/ceval.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Python/ceval.c#L2318)
126+
122127
```
123128
// Python/ceval.c
124129
@@ -147,6 +152,8 @@ python -m dis set_test.py
147152

148153
此时继续查看PySet_New函数的执行流程;
149154

155+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2286)
156+
150157

151158
```
152159
PyObject *
@@ -188,10 +195,12 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
188195

189196
从PySet_New的执行流程可知,字典的初始化过程就是初始化相关数据结构。
190197

191-
##### set的插入
198+
## set的插入
192199

193200
在本例的初始化过程中,由于传入了初始值1,2,所以会在执行字节码指令的时候,执行PySet_Add,该函数的本质与set_a.add(3)本质都调用了更底层set_add_key函数;
194201

202+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2338)
203+
195204
```
196205
197206
int
@@ -208,6 +217,8 @@ PySet_Add(PyObject *anyset, PyObject *key)
208217

209218
继续查看set_add_key函数的执行过程;
210219

220+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L419)
221+
211222
```
212223
static int
213224
set_add_key(PySetObject *so, PyObject *key)
@@ -226,6 +237,8 @@ set_add_key(PySetObject *so, PyObject *key)
226237

227238
该函数主要就是检查传入的key是否能够被hash,如果能够被hash则直接返回,如果能被hash则继续调用set_add_entry函数将值加入到set中;
228239

240+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L136)
241+
229242
```
230243
231244
static int
@@ -375,10 +388,12 @@ s.add(7) // index = 9 & 7 = 1
375388

376389
大致的set的插入过程执行完毕。
377390

378-
##### set的删除
391+
## set的删除
379392

380393
set的删除操作主要集中在set_remove()函数上,如下示例;
381394

395+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L1921)
396+
382397
```
383398
384399
static PyObject *
@@ -411,6 +426,8 @@ set_remove(PySetObject *so, PyObject *key)
411426

412427
此时就会调用set_discard_key方法来讲对应的entry设置为dummy;set_discard_key方法如下;
413428

429+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L447)
430+
414431
```
415432
416433
static int
@@ -430,6 +447,8 @@ set_discard_key(PySetObject *so, PyObject *key)
430447

431448
该函数主要就是做了检查key是否可用hash的检查,此时如果可用hash则调用set_discard_entry方法;
432449

450+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L400)
451+
433452
```
434453
435454
static int
@@ -454,11 +473,12 @@ set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
454473

455474
此时就是查找该值,如果找到该值并将该值设置为dummy,并且将used值减1,此处没有减去fill的数量,从此处可知,fill包括所有曾经申请过的数量。
456475

457-
458-
##### set的resize
476+
## set的resize
459477

460478
set的resize主要依靠set_table_reseize函数来实现;
461479

480+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L302)
481+
462482
```
463483
static int
464484
set_table_resize(PySetObject *so, Py_ssize_t minused)
@@ -543,6 +563,8 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
543563

544564
主要是检查是否table相同并且需要重新resize的值,然后判断是否fill与used相同,如果相同则全部插入,如果不同,则遍历旧table讲不为空并且不为dummy的值插入到新表中;
545565

566+
源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L267)
567+
546568
```
547569
static void
548570
set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)

0 commit comments

Comments
 (0)