Python-集合基础的详细讲解 Python——集合基础知识讲解,集合的小试牛刀
1.集合(set)的概述:
Python 中的集合与数学中集合(set)差不多一致,也是用于保存不重复的元素。它有可变集合(set)和不可变集合(frozenset)两种,在python中用到集合,多半是使用到了他的唯一性,或者是集合可加减性,不用怀疑。同样在自己写代码时如果要用到上面的也可以考虑来提高效率.
2.集合操作:
2.1集合的创建:
Python中提供了两种集合创建方式,第一种是字面量形式的创建,另一种是通过set()函数创建,显然第一种方式会比set()函数会快一点因为前者的时间复杂度可以看成是O (1),后者是O(n)
值得注意的是set(iterable)只有一个可迭代参数,初学者容易再次出错,如果不是一个可迭代都会报错
collection = {[value1,valu2]}
#collection = {1,2,3,5}
#这个会报错
#collection = {} 同样合法
collection = set([val1,val2])
#collection = set() 同样合法
2.2集合添加:
2.21.添加add():
通过add(val)添加元素,一帮情况下add只能添加一个元素,如果添加的不是一个元素,那么他会将他们打包成一个元组然后添加到里面去,但是不可变集合(Frozenset)是不能进行添加和删除的请看代码演示:
set_temp = set()
set_temp.add(2)
#结果是set_temp = {2}
set_temp.add((1,2,3))
#结果是set_temp = {2,(1,2,3)}
'''
值得一提的是add((val1,val2))合法但是add({val1,val2})或者add([val1,val2])就非法
在使用中一定要注意,并且最好不要用add()去添加多个元素
'''
值得一提的是add只有集合有这个,列表的是append(),用错了会报错,
同时用add添加不一定是按照末尾添加,注意很多博客这个地方有出入,绝对不能是一概而论是从末尾添加,如果全是int的话会比较值,放在合适的位置,如果是字符会比较ASCII码,如果类型不一规律比较复杂,下面的update()同样是这样
set_ = set({[1,2,3,4,5])
set_.add(0)
#set_ = {0,1,2,3,4,5}
2.22.添加update():
那么对于要添加多个元素我们可以用update,通过update(iterable)方法更新集合,但是不可变集合(Frozenset)是不能进行添加和删除的
其中iterable只能是可迭代的对象其中不论是元组,列表,集合都是合法,显然单个元素int,set用update会报错
set_ = set()
set_.update({val1,val2})
#其中是可以是dict,list,set,tupel
#对于传入的字典,集合只会添加键不会添加值
set_update({'a' : 123})
#结果是set_ = {'a'}
当然了既然是可迭代,那么任何你能想到的迭代器都可以往里面带,比如zip,map等从而衍生出一些高级的写法,当然了如果不知道map的用法,也可以先了解一下在来看下面,下面这种写法在Leetcode都十分常见
下面我们演示一下:统计用空格分隔输入的字符串中不重复元素(显然首先想到用集合的去重):
set_ = set()
set_.update(map(int,input().split()))
##输入 1 2 3 4 4 4 4 5 6
##set_ = {1,2,3,4,5,6}
2.3删除
2.31del &clear()
del不仅仅只是在集合中存在,对一个变量,一个列表,,字典等都有这个语法,如果是可迭代的列表某个索引的删除就相当于是把当前删除,然后后面的依次往前挪一个位置,当然了如果是Counter()计数的哈希映射,则是直接删除当前映射,
li = []
dic = {}
def li
del dic
#以上是直接删除全部列表和字典
clear()实现的是清空整个集合
2.32删除指定元素discard():
collection = {2,3,5}
collection.discard(2)
#删除了集合中的2
collection.discard(4)
#记住,集合没有索引,但是可迭代,但是其中没有4可删除
#那么也不会报错,如果没有就上面都没有执行
2.33删除remove()
这个和discard()最大的区别就是remove(object)如果集合中不存在该元素,那么就会报错,但是discard却不会报错,因此在使用我们通常使用remove
值得注意的还有一点,如果只是删除一个元素用remove()可以,但是如果在删除多个元素或者要对多个元素进行判断后删除用remove通常会出错,尤其是for + remove这两个扫把星组合,因为remove会删除第一个值出现的值,然后把后面的元素往前挪移个位置,但是for在索引是一置不断往后,这样就会忽略掉remove删除前的该值的后面的值的判断,当然这一般出现在列表中
2.34pop()
通过pop()来删除最上面的数,注意pop()这个函数是没有任何参数的,带参数就报错
set_ = {0,1,2,3,4,5}
set_.pop()
#结果是set_ = [1,2,3,4,5]
2.4集合交集并集差集数学运算:
&表示交集,|表示并集,^表示差集
例题
下面有一道中等难度Leetcode 的例题来说明用好集合的好处,并结束这篇博客
Eg:检查一个二进制字符串是否包含所有k长度的字串:给你一个二进制字符串 s
和一个整数 k
。如果所有长度为 k
的二进制字符串都是 s
的子串,请返回 true
,否则请返回 false
。
class Solution:
def hasAllCodes(self, s: str, k: int) -> bool:
#长度为n的二进制有2^n种组合:,我们可以用一个滑动窗口来看如果找到了2^n个不同 窗口就返回
res = set() ###不能用res = {}非法
for i,x in enumerate(s):
if i < k - 1:
continue
res.add(s[i-k+1:i+1]) ### 笔者想了好久才发现是这个,最开始容易写成 s[i-k+1:i]
if len(res) == 2**k : ###这个判断必须放在最后面,如果放在for下面第一行,可能最后一组加上刚好True
return True ###m其中有个测试就是
return False
#这题用集合比用列表判断相关字串在不在里面消耗更多时间会超时
#如果是列表的话
#if path in ans :
# pass
#else:
# ans.append(path)
显然用集合的效率肯定比用列表每次都去判断高效的多。
给你一个字符串 s
,请你返回满足以下条件且出现次数最大的 任意 子串的出现次数:
- 子串中不同字母的数目必须小于等于
maxLetters
。 - 子串的长度必须大于等于
minSize
且小于等于maxSize
。输入:s = "aababcaab", maxLetters = 2, minSize = 3, maxSize = 4 输出:2 解释:子串 "aab" 在原字符串中出现了 2 次。 它满足所有的要求:2 个不同的字母,长度为 3 (在 minSize 和 maxSize 范围内)。
from collections import Counter class Solution: def maxFreq(self, s: str, maxLetters: int, minSize: int, maxSize: int) -> int: n = len(s) cnt = collections.defaultdict(int) #调用colleciotns里面的字典库来计数,把没有出现过的子字符串都初始化为int的初始变量 for i in range(n - minSize + 1): temp = s[i:minSize + i] c = set(temp) #利用到了集合的去重性 if len(c)
感谢大家耐心的看完!