Set及操作

2020-03-31  本文已影响0人  西西里加西

Set及操作

约定概念/叫法:

set是可变的、无序的、不重复的元素的集合

set的定义/初始化

set()   
set(iterable)

实例:

In [1]: s1 = set()

In [2]: s1
Out[2]: set()
In [3]: set(range(5))
Out[3]: {0, 1, 2, 3, 4}

In [4]: set(list(range(5)))
Out[4]: {0, 1, 2, 3, 4}

错误的创建空集合的方法

In [7]: s4 = {} # 生成空字典

In [8]: type(s4)
Out[8]: dict

直接表示集合

>>> s5 = {5,6,7,8}
>>> print(s5, type(s5))
{8, 5, 6, 7} <class 'set'>

set可以存储不同类型的数据

>>> s6 = {(1,2), 3, 'a'}
>>> print(s6, type(s6))  
{(1, 2), 3, 'a'} <class 'set'>

set不能存储不可哈希的数据类型,例如列表

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

set的元素

set操作

增加

add()

update(*others)

删除

remove(elem)

discard(elem)

pop() --> item

clear()

set修改

要么增加,要么删除,没有直接修改原本存在的元素的方法

为什么?-- 因为集合不是线性结构,对于每个元素的标识就是值本身的哈希值,所以不可能用标识符重新赋值

set查询

集合是非线性结构,无法索引

set遍历

可以遍历

set的成员运算符

可以使用 in,not in

效率怎样?-- 效率高,因为集合内部使用哈希值来标记元素

list和set成员运算符的效率比较

根本不是一个量级的对比......

# python3 -m timeit -r 5 -n 5 -s "s = set(range(10000000))" "print(-1 in s)"      
5 loops, best of 5: 9.02 usec per loop

# python3 -m timeit -r 5 -n 5 -s "lst = list(range(10000000))" "print(-1 in lst)"  
5 loops, best of 5: 117 msec per loop

set和线性结构

线性结构的查询的时间复杂度是O(n),即随着数据规模的增大而增加耗时

set、dict等结构,内部使用hash值作为key,时间复杂度可以做到O(1),查询时间和数据规模无关

可hash的对象有哪些

以上都是不可变类型,是可哈希类型(hashable)

再次强调:set的元素必须是hashable的

集合

基本概念

集合运算

并集

将两个集合A和B的所有元素合并到一起,组成的集合称作集合A和集合B的并集。

union(*others) # 返回和多个集合合并之后的新的集合

| # 运算符重载,等同union

update(*others) # 和多个集合合并,就地修改

|= # 等同于update

交集

集合A和B,由所有属于A且属于B的元素组成的集合。

intersection(*others) # 返回和多个集合的交集

& # 和intersection一样

intersection_update(*others) # 获取和多个集合的交集,并就地修改

&= # 和intersection_update一样

差集

集合A和B,由所有属于A且不属于B的元素组成。

difference(*others) # 返回和多个集合的差集

- # 等同difference

difference_update(*others) # 获取和多个集合的差集

-= # 等同于difference_update

对称差集

集合A和B,由所有不属于A和B的交集的元素组成。

symmetric_difference(other) # 返回和另一个集合的对称差集

^ # 和symmetric_difference一样

symmetric_difference_update(other) # 获取和另外一个集合的对称差集就地修改

^= # 等同于symmetric_difference_update

就地修改:使用函数的集合会被修改,且没有返回值

返回:调用以上方法的集合不会被修改,有返回值,返回值就是想要的结果

判断运算

issubset(other) 或者 <=

A < B

issuperset(other)、>=

A > B

isdisjiont(other)

集合的应用场景

练习

随机生成两个10个数字的列表,每个数字取值范围【10,20】,如:

​ a = [19, 15, 19, 10, 15, 13, 14, 16, 12, 13]

​ b = [10, 14, 11, 14, 10, 15, 10, 13, 10, 19]

统计20个数字之中,一共有多少不同的数字?

2组之间进行比较,不同的数字有几个,分别是什么?

2组之间进行比较,相同的数字有几个,分别是什么?

import random

lst_1 = random.choices(list(range(10, 20)), k=10)
lst_2 = random.choices(list(range(10, 20)), k=10)
print(lst_1)
print(lst_2)

set1 = set(lst_1)
set2 = set(lst_2)
print()
print('20个数字中有{}个不同的数字'.format(len(set1 | set2)))
print()
print('2组之间进行比较,不同的数字有{}个,分别是{}'.format(len(set1.symmetric_difference(set2)), set1.symmetric_difference(set2)))
print()
print('2组之间进行比较,相同的数字有{}个,分别是{}'.format(len(set1.intersection(set2)), set1.intersection(set2)))
>>> [17, 19, 19, 10, 13, 18, 18, 12, 10, 18]
>>> [14, 19, 19, 17, 12, 16, 17, 14, 13, 14]
>>> 
>>> 20个数字中有8个不同的数字
>>> 
>>> 2组之间进行比较,不同的数字有4个,分别是{16, 18, 10, 14}
>>> 
>>> 2组之间进行比较,相同的数字有4个,分别是{17, 19, 12, 13}
上一篇 下一篇

猜你喜欢

热点阅读