python集合(set)

1、集合set
  约定:
    set翻译为集合
    collection翻译为集合类型,是一个大概念
  set:
    可变的、无序的、不重复的元素的集合
  构造方法:
    set()  →  new empty set object
    set(iterable)  →  new set object

# -*- coding:utf-8 -*-
# version:python3.7

s1 = set()    # empty set
s2 = {1,2,3}  # set
s3 = {}       # dict:字典,not set
s4 = set(range(5))
s5 = {'abc',1,1,2,2,3,3,'abc'}    # set:去重
print(s1,type(s1))
print(s2,type(s2))
print(s3,type(s3))
print(s4)
print(s5)

执行结果:
set() <class 'set'>
{1, 2, 3} <class 'set'>
{} <class 'dict'>
{0, 1, 2, 3, 4}
{1, 2, 3, 'abc'}

  set的元素要求必须可以hash
  目前学过的不可hash的类型有list、set

# -*- coding:utf-8 -*-
# version:python3.7

s1 = {1,2,'abc',(3,),[4]}
print(s1)

执行结果:报错
TypeError s1
= {1,2,'abc',(3,),[4]} TypeError: unhashable type: 'list'

  元素不可以使用索引
  set可以迭代

2、set的增删改查
  1>add(elem)
    增加一个元素到set中
    如果元素存在,什么都不做

  2>update(*others)
    合并其他元素到set集合中来
    参数others必须是可迭代对象
    就地修改

  3>remove(elem)
    从set中移除一个元素
    元素不存在,抛出KeyError异常,Key:唯一

  4>discard(elem)
    从set中移除一个元素
    元素不存在,什么都不做

  5>pop()  →  item
    移除并返回任意的元素
    空集返回KeyError异常

  6>clear()
    移除所有元素

# -*- coding:utf-8 -*-
# version:python3.7

s1 = {1,2,3}
print(s1)
s1.add(4)    # 增加
print(s1)
s1.update(range(6))    # 合并其他元素到该集合,并去重
print(s1)
s1.remove(1) # 移除
print(s1)
s1.discard(11)         # 移除,元素不存在,什么都不做
print(s1)
s1.pop()     # 弹出
print(s1)

执行结果:
{1, 2, 3}
{1, 2, 3, 4}
{0, 1, 2, 3, 4, 5}
{0, 2, 3, 4, 5}
{0, 2, 3, 4, 5}
{2, 3, 4, 5}

  修改
    要么删除,要么加入新的元素,没有修改
  查询
    非线性结构,无法索引
  遍历
    可以迭代所有元素
  成员运算符
    in和not in判断元素是否在set中,效率呢?

  在 IPython 中进行测试:

 

 

  经测试,线性结构的查询时间复杂度是O(n),即随着数据规模的增大而增加耗时,set、dict等结构,内部使用hash值作为key,时间复杂度可以做到0(1),查询时间和数据规模无关

  可hash
    数值型int、float、 complex
    布尔型True、False
    字符串string、bytes
    tuple
    None
  以上都是不可变类型,是可哈希类型,hashable

  set的元素必修都是可hash的

3、集合基本概念
  1>全集
    所有元素的集合,例如实数集,所有实数组成的集合就是全集

  2>子集subset和超集superset
    一个集合A所有元素都在另一个集合B内,A是B的子集,B是A的超集

  3>真子集和真超集
    A是B的子集,且A不等于B,A就是B的真子集,B是A的真超集

  4>并集:多个集合合并的结果
    union(*others)
      返回和多个集合合并后的新集合
    | 运算符重载
      等同union

    update(*others)
      和多个集合合并,就地修改
    |=
      等同update

  5>交集:多个集合的公共部分
    intersection(*others)
      返回和多个集合的交集
    &
      等同于intersection

    intersection_update(*others)
      获取和多个集合的交集,并就地修改
    &=
      等同于intersection_update

  6>差集:集合中除去和其他集合公共部分
    difference(*others)
      返回多个集合的差集
    -
      等同于difference

    difference_update(*others)
      获取和多个集合的差集并就地修改
    -=
      等同于difference_update

  7>对称差集
    集合A和B,由所有不属于A和B的交集元素组成的集合,记作(A-B)∪(B-A)
    symmetric_differece(other)
      返回和另一个集合的差集
    ^
      等同symmetric_differece

    symmetric_differece_update(other)
      获取和另一个集合的差集并就地修改
    ^=
      等同symmetric_differece_update

  8>issubset(other)、<=
      判断当前集合是否是另一一个集合的子集
    set1 < set2
      判断set1是否是set2的真子集
    issuperset(other)、>=
      判断当前集合是否是other的超集
    set1 > set2
      判断set1是否是set2的真超集
    isdisjoint(other)
      当前集合和另一个集合没有交集
    没有交集,返回True

4、集合应用:
  1>共同好友(交集运算)
  你的好友A、B、C,他的好友C、B、D,求共同好友

  2>微信群提醒
  X与群里其他人都不是微信朋友关系!
    并集:userid in (A | B | C ...) == False,A、B、C等是微信好友的并集,用户ID不在这个并集中,说明他和任何人都不是好友
    群里所有其他人ids都不在X的朋友列表中T & ids == set()

  3>权限判断
  有一个API,要求权限同时具备A、B、C才能访问,用户权限是B、C、D,判断用户是否能够访问该API
         API集合A,用户权限集合P。要用户权限全部包含API权限要求。
         A-P= set(),A-P为空集,说明P包含A
         A.issubset(P)也行,A是P的子集也行
         A&P= A也行

  有一个API,要求权限具备A、B、C任意一项就可访问,用户权限是B、C、D,判断用户是否能够访问该API
         API集合A,权限集合P
         A&P != set()就可以
         A.isdisjoint(P) == False表示有交集

  4>一个总任务列表,存储所有任务。一个完成的任务列表。找出为未完成的任务
    业务中,任务ID一般不可以重复
    所有任务ID放到一个set中,假设为ALL
    所有已完成的任务ID放到一个set中,假设为COMPLETED,它是ALL的子集
    ALL- COMPLETED = UNCOMPLETED

  5>随机产生2组各10个数字的列表,如下要求:
    每个数字取值范围[10,20]
    统计20个数字中,一共有多少个不同的数字?               #set()去重,求交集
    2组之间进行比较,不同的数字有几个?分别是什么?    #对称差集
    2组之间进行比较,相同的数字有几个?分别是什么?    #求交集
    a=[1,9,7,5,6,7,8,8,2,6]
    b=[1,9,0,5,6,4,8,3,2,3]



posted @ 2020-03-31 15:43  我听过  阅读(793)  评论(0编辑  收藏  举报