热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python逻辑讲解_python10set详解

集set约定set翻译为集collection翻译集合类型,是一个大概念set可变的、无序的、不重复的元素的集合但是也有顺序集合,比如java当中的tr

集 set

约定

set 翻译为集

collection 翻译集合类型,是一个大概念

set

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

但是也有顺序集合,比如java当中的treeset,有排序的

集当中的元素是散放的,是一个散列值,是个哈希。

python当中所有数据结构,在其他语言当中都能够找到。

列表更适合尾部追加,两头要操作就要用queue。

前面学过的可变的,就是bytearray,list。

可变不可变,指的就是能不能就地修改。

集合当中的元素,本身就是不能重复的。

集合最大的一个用处,就是去重。

set定义 初始化

set() -> new empty set object

set(iterable) -> new set object

s1 = set()

s2 = set(range(5))

s3 = set(list(range(10)))

s4 = {} # dict

s5 = {9,10,11} # set

s6 = {(1,2),3,'a'}

s7 = {[1],(1,)1} # ?

s = set(enumerate(range(10)))

s = set(range(10))

s = {}

type(s) # dict,集合当中什么都不写,这个就是字典了

s = {1}

type(s) # set

s1 = set() # 这个才是定义一个空的字典。

s = {(1,2),2,None}

s = {(1,2),2,None,'abc',b'abc',[1]} # unhashable type : 'list'

# list是一个不可哈希类型的。

# set当中的元素,要么都是不可变类型,要么就是一个单值。

s = {(1,2),2,None,'abc',b'abc',bytearray(b'abc')}

集合很重要的一个特点,就是无序、去重。

在python当中有可变不可变的区别。

set的元素

set的元素必须可以hash

目前学过的不可hash的类型有list,set

元素不可以索引

set可以迭代

hash('abc')

hash(b'abc')

上面两个哈希值一样

hash(10000000)

hash(1)

s = set(['abc',b'abc']) # 'abc',b'abc'两个哈希值一样,但是可以存进去的。

set??

set(s)

无序是迭代的,不可以索引,成员运算符,是可以的。

set增加

add(element)

增加一个元素到set当中

如果元素存在,什么都不做

update(*others

合并其他元素到set集合当中来

参数others必须是可迭代对象

就地修改

s = add(2)

s = update({1,2,3}) # 这个就是在做集合运算了

s = update([1,2,3],[1,3,4]) # 给了两个集合,把多个集合合并到当前集合

s = update([1,2,3],[1,3,4],(11,23,45))

s = update([1,2,3],[1,3,4],[11,23,45])

set删除

remove(element)

从set中移除一个元素

元素不存在,抛出来keyError异常

discard(element)

从set中移除一个元素

元素不存在,什么都不做

pop() -> item

移除并返回任意的元素,为什么是任意元素

空集返回KeyError异常

clear()

移除所有元素

移除的方式,就是求了元素的哈希值。

顺序结构的移除,就是要遍历一遍的。用索引,找的过程很快。

找到这个值,就是O(1)的。

但是移除这个值之后,后面的元素都要向前补充一下,所以速度慢。

但是集合是通过值的hash来进行移除的,这个hash就是相当于值的key。

移除了之后,大家也不用移动位置。

所以效率还是很高的。

pop?

help(s.pop())

s.pop()当中不要传参数

a = s.pop()

remove和pop都是要产生异常的,用的时候要注意异常处理

discard是弃用的意思,元素不存在,什么都不做,应该是比较安全的方法,相对于remove

这里remove和pop都会面临到异常处理的问题,discard就没有这个问题。

总结:

1. remove() 有异常处理

2. pop() 有异常处理

3. discard() 无异常处理

4. clear() 无异常处理

移除元素,都会面临到一个垃圾回收的问题。

set修改、查询

修改

要么删除,要么加入新的元素,因为没有重复的元素,修改就是新的。

为什么没有修改?

查询

非线性结构,无法索引

遍历

可以迭代所有元素

成员运算符

in 和 not in判断元素是否在set当中

效率呢?

这个效率是相当高的,相当于用索引访问线性结构

非线性结构用哈希值来定位,相当于用索引遍历列表

时间复杂度,就是相当于O(1)

set成员运算符的比较

list和set的比较

lst1 = list(range(100))

lst2 = list(range(1000000))

-1 in lst1、-1 in lst2 看看效率,随着规模的增加,应该时间会很低。

set1 = set(range(100))

set2 = set(range(1000000))

-1 in set1、-1 in set2 看看效率,随着规模的增加,应该没有多大区别。

%%timeit lst1 = list(range(100))

-1 in lst1 # 这个就是true或者false的问题。-1必须遍历全部。

%%timeit set1 = set(range(100)) # set_up_code 不计时了

-1 in set1 # 这个就是true或者false的问题。-1必须遍历全部。

当我们判断或者迭代的时候,用set效率会更高。

set和线性结构

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

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

可hash

数值型:int float complex # 字面常量

布尔值:True False # 整形的子类

字符串:String bytes # 字面常量

tuple

None

以上都是不可变类型,成为可哈希类型,hashable

set的元素必须是可以hash的。

这里不要和可迭代对象搞混了,只要可迭代对象当中的元素是可以哈希的,那么就可以

s = set(list)这种用法

集合

基本概念

全集

所有元素的集合,例如实数集,所有实数组成的集合,就是全集

子集subset和超集superset

一个集合A所有元素都在另外一个集合B内,A是B的子集,B是A的超集

真子集合真超集

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

并集:多个集合合并的结果

交集:多个集合的公共部分

差集:集合当中除去和其他集合公共部分

集合类型当中用的最多的,就是list,和dict。

循环和递归,刚释放变量,一定要释放一下,

尤其是用到大数据规模的情况下,一定要测试一下。

可能会出现内存被耗尽的情况。

本来是虚拟地址,内存不够开了,

就要将内存当中的数据,不常用的,导入到swap当中,

windows当中叫做虚拟内存。

本来磁盘都是机械装置,有一个寻道。

速度是很慢的。

所以从内存到swap,从swap到内存,是很慢的。

磁盘大多数都是随机访问的。

所以,磁盘比磁带的好处,在于把顺序变成随机的。

后来出现了电路,后来出现了固态硬盘。

后来不用机械式了。

还是有寻道的问题,还有生产的良品率的问题。

你还要求空间比较小。

所以磁盘还是大量应用的。

遇到磁盘的时候,一定要小心,一定有考虑效率。

尽量要放在内存当中用。

但是不用磁盘也不行,没有副本,就没办法冗余了。

一边计算一边落地,有很多问题是需要考虑的。

线性结构的查询是随着规模变大就很耗时了。

所以一般规模比较大的时候,就要用到排序,

然后我们再进行查询,这个就很好了。

就不用顺序查找了,就可以折半了。

对于非线性结构,列表类似于数组,但是包装的要多一点。

set和dict,这几个东西,一定要搞清楚。

有这三个东西,基本上可以走遍天下了。

但是set和dict可以理解为一种,set可以理解成为特殊的字典。

内部使用hash作为key,有一个hash空间的问题。

有的叫哈希桶的,用来指代很大的散列空间,叫做值域。

值是散列的,是稀疏的。

基于hash的,时间复杂度,可以做到big O(1)

现在没有提空间复杂度。

空间复杂度,比如冒泡法,就开辟了一个temp,就多了一个。

空间复杂度,杨辉三角的时候,就有很大差异。

算法,就要空间复杂度和时间复杂度,都要优化好。

append的,空间复杂度就很高。

集合运算

并集

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

union(*others)

返回和多个集合合并后的新的集合

| 运算符重载

等同 union

update(*others)

和多个集合合并,就地修改

|=

等同update

union就是联合,合并的意思,可以用|符号

update,多个集合的合并,是就地修改的。

|=,相当于+=

a |= {1,2} | {2,3}

交集

集合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的交集元素组成的集合,记作(A-B)U(B-A)

symmetric_differenc(other)

返回和另一个集合的差集

^

等同于symmetric_differece

symmetric_difference_update(other)

获取和另外一个集合的差集并就地修改

^=

等同symmetric_difference_update

issubset(other)、<&#61;

判断当前集合是否是另一个集合的子集

set1

判断set1是否是set2的真子集

issuperset(other)、>&#61;

判断当前集合是否是other的超集

set1 > set2

判断set1是否是set的真超集

isdisjoint(other)

当前集合和另一个集合没有交集

没有交集&#xff0c;返回True

集合应用

共同好友

你的好友是ABC&#xff0c;他的好友是CBD&#xff0c;你们的共同好友是谁&#xff1f; FOF算法。

有了共同好友&#xff0c;才可以推荐

在生产过程当中基本上就是在redis当中做集合运算的。

交集问题&#xff1a;{&#39;A&#39;,&#39;B&#39;,&#39;C&#39;}.intersection({&#39;B&#39;,&#39;C&#39;,&#39;D&#39;})

微信群提醒

XXX与群里其他人都不是微信朋友关系

你要把业务映射成为脑子当中的逻辑

每个人登录会加载自己的好友信息&#xff0c;如果用select语句去查数据库&#xff0c;就是相当的复杂

并集&#xff1a;user id(A|B|C|...) &#61;&#61; False,A、B、C等是微信好友的并集&#xff0c;用户ID不在这个并集当中&#xff0c;说明他和任何人都不是朋友。

权限判断

有一个API&#xff0c;要求权限同时具备A、B、C才能访问&#xff0c;用户权限是B、C、D&#xff0c;判断用户是否能够访问该API

有一个API&#xff0c;要求权限具备A、B、C任意一项就可以访问&#xff0c;用户权限是B、C、D&#xff0c;判断用户是否能够访问该API

API集合A&#xff0c;权限集合P

A-P &#61; {}&#xff0c;A-P为空集&#xff0c;说明P包含A

A.issubset(P)也行&#xff0c;A是P的子集也行

A & P &#61; A也行

API集合A&#xff0c;权限集合P

A & P &#xff01;&#61;{} 就可以

A.isdisjoint(P)&#61;&#61;False 表示有交集

一个总任务列表&#xff0c;存储所有任务&#xff0c;一个完成的任务列表&#xff0c;找出没有完成的任务。

业务中&#xff0c;任务ID一般不可以重复

所有任务ID放到一个set当中&#xff0c;假设为ALL

所有已完成的任务ID放到一个set当中&#xff0c;假设为COMPLETED&#xff0c;它是ALL的子集。

ALL - COMPLETED &#61; UNCOMPLETED

集合练习

随机产生2组各10个数字的列表&#xff0c;如下要求

每个数字取值范围[10,20]

统计20个数字当中&#xff0c;一共有多少个不同的数字&#xff1f;

2组当中&#xff0c;不重复的数字有几个&#xff1f;分别是什么&#xff1f;

2组当中&#xff0c;重复的数字有几个&#xff1f;分别是什么&#xff1f;

import random

a &#61; []

b &#61; []

num &#61; list(range(10,21))

for _ in range(10);

a.append(random.randrange(10,21))

b.append(random.randrange(10,21))

#a &#61; [1,9,7,5,6,7,8,8,2,6]

#b &#61; [1,9,0,5,6,4,8,3,2,3]

#--------------------------

s1 &#61; set(a)

s2 &#61; set(b)

print(s1)

print(s2)

print(s1.union(s2)) # 并集

print(s1.symmetric_differece(s2)) # 对称差集

print(s1.intersection(s2)) # 交集

集合运算做小集合&#xff0c;问题不大的。

两个集合&#xff0c;如果都是10万级别的&#xff0c;求并集&#xff0c;要么修改自身&#xff0c;要么产生新的集合。

如果三个、四个10万的集合交集、并集、差集呢&#xff1f;

这个时候最好就要测试一下。

内存有的情况&#xff0c;就是可以开辟。

内存没有的时候&#xff0c;就是要考虑垃圾回收&#xff0c;要考虑程序效率了。

这个时候更要考虑空间复杂度。

Java、Python都要考虑这个问题&#xff0c;虚拟机语言。

C&#43;&#43;就没有垃圾回收&#xff0c;就会容易产生内存碎片。

内存空洞、碎片&#xff0c;那么如何开辟大内存。

减少数据库负担的时候&#xff0c;拿出来的数据就要常驻内存。

集合运算我们要用&#xff0c;字典运算很少听到。



推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • Explain如何助力SQL语句的优化及其分析方法
    本文介绍了Explain如何助力SQL语句的优化以及分析方法。Explain是一个数据库SQL语句的模拟器,通过对SQL语句的模拟返回一个性能分析表,从而帮助工程师了解程序运行缓慢的原因。文章还介绍了Explain运行方法以及如何分析Explain表格中各个字段的含义。MySQL 5.5开始支持Explain功能,但仅限于select语句,而MySQL 5.7逐渐支持对update、delete和insert语句的模拟和分析。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
author-avatar
晓云71_783
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有