Python 有趣ヾ(≧▽≦*)o SET 集合类型

Python 有趣ヾ(≧▽≦*)o SET 集合类型


一、集合的概念

集合(Set),是Python的数据类型之一,这于数学中的集合概念是一样的
在讲解 Python 的集合之前,我觉得还是有必要先回顾一下数学集合中的主要分类:并集,交集,差集
在这里插入图片描述

Python中的集合

如果有需要的时候,Python的集合绝对是一个很方便的数据类型

Python集合特点

  1. 天生去重性,每个元素都是唯一,互不相同,这是也是集合最主要的特点
  2. 只能存储不可变的元素,对于列表、字典这些可变数据类型是不能存储在集合里的
  3. 集合属于 无序

简单概况: 集合是一个无序且不重复的数据类型


二、新建一个集合🤶🏻

在Python中,新建一个集合常用的方法有两种

  1. 通过对象实例化创建

    • 若是一个空集合,直接使用 set() 内置函数即可,如 s = set(), 此时 s 就是一个空集合的变量
    • set() 还能通过将其他数据类型转换成集合来获取集合
      可以看到字符串中有很多个1,可由于集合的去重性,实质上只有最后一个1被保存了下来
      s = set("1234511")
      print(s)				# 结果为 {'2', '4', '3', '5', '1'}
      
      在下面内容的示例中,我将用 set() 配合 range() 内置函数,来快速新建一个字典
  2. 直接定义

    可以通过类似其他数据类型定义的语法来直接新建一个集合
    值得注意的是,集合的符号和字典用的都是花括号,但字典是带冒号的键值对书写格式,集合是以逗号分割的书写格式

    # 字典的定义
    dic = {"语言": "Python", "上手": "简单"}
    # 集合的定义
    s = {1, 1, 1, 1, '亲', '爱', '的', '读', '者', '你', '好'}
    

三、利用去重性👲🏻

上面已经提到过了,集合天生去重,那么可以利用集合的去重性去做一些事情

张三使用了障眼法,造出了多个假的张三,看看罗老师如何去治张三

# name = ['张三', '张三', '张三', '张三', '张三', '张三', '张三', '张三', '张三', '张三', '罗翔']
name = ["张三"] * 10             # 也可以这样去添加多个张三
name.append("罗翔")
name = set(name)
print(name)
{'罗翔', '张三'}

是吧,使用集合一下就能破解张三的障眼法,揪出唯一的一个张三

接下来看一个去重性的应用,不重复抽奖

程序逻辑: 使用到了random 标准库 随机选出一个名字,在将此名字添加到集合里,如果是重复的将不进行添加操作,循环条件为判断集合人数是否小于3

import random

selected, name = set(), ["张三", "李四", "小明", "李华", "约翰", "Jone", "Mark", "Bill", "PrettyGirl"]
while len(selected) < 3:
    selected.add(random.choice(name))
print(selected)

四、集合+运算符🏆

集合+运算符,我个人觉得,这是Python集合的一个精髓,使用起来非常方便

分别新建两个集合 A 与 B

A = {"西红柿", "橘子", "香蕉", "菠萝", "胡萝卜", "土豆"}
B = {"香蕉", "胡萝卜", "西红柿", "苹果", "生菜"}
  • 并集

    print(A | B)        # 并集
    
    {'西红柿', '苹果', '菠萝', '胡萝卜', '香蕉', '生菜', '橘子', '土豆'}
    
  • 交集

    print(A & B)        # 差集
    
    {'西红柿', '胡萝卜', '香蕉'}
    
  • 差集

    print(A-B)      # 属于A但不属于B
    print(B-A)      # 属于B但不属于A
    
    {'菠萝', '土豆', '橘子'}
    {'苹果', '生菜'}
    

上面使用运算符返回的结果均为集合类型


五、集合的方法

下面将讲解Python中的集合对象,都拥有什么样的方法

1) .add(elem)

将元素 elem 添加到集合中
因为是添加到集合,如果添加元素已存在,则不进行操作

s = set(range(1, 10))
print(s)	
s.add(0)					# 添加一个元素0
s.add(10)					# 添加一个元素10
print(s)		
s.add(2)					# 再次添加一个元素2
print(s)
{1, 2, 3, 4, 5, 6, 7, 8, 9}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

2) .update(others)

更新(update)集合,添加来自 others 中的所有元素,如果添加元素已存在,则不进行操作

这个 elems 传入的是一个可迭代对象,这意味着可以传入 字符串、元组、列表等数据类型

s = set(range(1, 6))
print(s)
s.update({6: 5, 8: 1, 7: 2})        # 是字典,则取Key值
s.update("你好世界")               # 是字符串,则取每个字符
s.update([11, 12, 13])
s.update({11, 12, 13})              # 和上面列表元素重复,不做任何操作
print(s)
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5, 6, 7, 8, '界', 11, 12, 13, '好', '你', '世'}

3) .remove(elem)

从集合中移除元素 elem
如果 elem 不存在于集合中则会引发 KeyError,可以先判断此元素是否存在

s = set(range(1, 10))
target = 1
if target in s:						# 判断此元素是否存在
    s.remove(target)

4) .discard(elem)

如果元素 elem 存在于集合中则将其移除

这个方法就像是 .remove() + 判断此元素是否存在 的结合版

s = set(range(1, 10))
target = 1
s.discard(target)
s.discard(target)           		# 此时元素并不存在,但不会报错

5) .pop()

从集合中移除并返回任意一个元素,其实就是随机移除一个元素并返回
如果集合为空则会引发 KeyError,可以先判断集合是否为空

嘛~♪(´▽`),上面这些都是官方手册里的说法,可实际使用时会发现,这不完全正确,.pop() 方法有时能随机移除元素,可有时又不能,我们来看看这是为什么🍺

通过实际使用的时候,我发现 .pop() 方法的效果有这几种情况:👇

  1. 集合中的元素都为数字时:

    会移除最小的数字,并将改数字返回,并不为随机

    s = set(range(1, 10))
    print(s)
    print(s.pop())
    print(s)
    
    {1, 2, 3, 4, 5, 6, 7, 8, 9}
    1
    {2, 3, 4, 5, 6, 7, 8, 9}
    
  2. 集合中的元素都为非数字时:

    确实与官方手册说法相符,能够随机删除非数字内容,并将其返回

    s = set("你好世界Python")
    print(s.pop())
    
  3. 集合中的元素既有数字也有非数字:

    这种情况相当于结合了上面两种,如果随机到的是数字则按照数字的方式来,非数字则安装非数字的方式来

    s = set("你好世界Python")
    s.update(set(range(1, 6)))
    print(s.pop())
    

我是在用 .pop() 对全是数字的集合进行测试时,发现每次移除并返回的都是同一个元素,我以为是巧合,可我再进行几十次测试后发现并不是这么一回事,最终发现了这个规则。
这个方法是不是感觉有些鸡肋?但其实可以考虑应用在抽奖等方向上

s_user = {"张三", "李四", "小美", "王华", "小明", "李华"}
awarded = []
while len(awarded) < 3:
    awarded.append(s_user.pop())
print(f"获奖用户: {' '.join(awarded)}")

6) .difference_update(elems)

更新集合,移除也存在于 others 中的元素,也就是移除两个集合中都存在的元素

s = set(range(10))
s.difference_update({1, 5, 6})
print(s)
{0, 2, 3, 4, 7, 8, 9}

7) .copy()

返回这个集合的浅copy

关于copy,Python分深浅Copy两种

s = set(range(10))
new_s = s.copy()

8) .clear()

移除集合中的所有元素

s = set(range(10))
s.clear()

9) .isdisjoint(other)

判断该集合与other集合是否包含相同的元素,如果没有返回 True,否则返回 False

s = set(range(10))
print(s.isdisjoint({1, 2, 3}))

如果当两个集合都为空时,返回 True

print(set().isdisjoint(set()))					# 返回True

10) .difference()

返回集合的差集,此方法作用与 四、集合+运算符🏆 中使用运算符 - 一样

A = {"西红柿", "橘子", "香蕉", "菠萝", "胡萝卜", "土豆"}
B = {"香蕉", "胡萝卜", "西红柿", "苹果", "生菜"}
print(A.difference(B))
print(B.difference(A))
{'土豆', '菠萝', '橘子'}
{'苹果', '生菜'}

11) .intersection()

返回集合的交集,此方法作用与 四、集合+运算符🏆 中使用运算符 & 一样

A = {"西红柿", "橘子", "香蕉", "菠萝", "胡萝卜", "土豆"}
B = {"香蕉", "胡萝卜", "西红柿", "苹果", "生菜"}
print(A.intersection(B))
{'西红柿', '香蕉', '胡萝卜'}

12) .union()

返回集合的并集,此方法作用与 四、集合+运算符🏆 中使用运算符 | 一样

A = {"西红柿", "橘子", "香蕉", "菠萝", "胡萝卜", "土豆"}
B = {"香蕉", "胡萝卜", "西红柿", "苹果", "生菜"}
print(A.union(B))
{'西红柿', '苹果', '菠萝', '胡萝卜', '香蕉', '生菜', '橘子', '土豆'}

参考资料💌

由衷感谢💖


相关博客😏

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值