蓝桥国三
日常训练时的万字整理
涵盖了比赛能用的很多技巧
目录
- 1. Itertools:排列组合
- 2. enumerate 详解
- 3.堆 heapq:用在前 K 个高频元素
- 4. map(函数,列表) 详解
- 5. sorted 如果第一个条件 相同 则按第二个条件排序
- 6. join方法:列表变字符串
- 7. 几种COPY方式
- 8. 进制转换
- 9. 匿名函数lambda 详解
- 10.小数转分数:fractions
- 11.GCD和LCM:最大公约数 最小公倍数
- 12.字符串以及数字格式化详解(前后补零)
- 13.几种取整
- 14.BFS迭代法:二叉树的层序遍历模板
- 15.print()详解
- 16.科学计数法
- 17.Counter:统计容器中各元素的个数并返回成字典
- 18.ASCII码与字符相互转换
- 19.zip()的使用
- 20.字典的值为列表或字典
- 21.集合运算
- 22.最优复杂度 求质数
- 23.处理日期类题目的无敌工具datetime
- 24.幂的代替:左右移动位运算
- 25.BFS遍历:迷宫 模板
- 26.读取txt文件
1. Itertools:排列组合
在Python中,迭代器(Iterator)是常用来做惰性序列的对象,只有当迭代到某个值的时候,才会进行计算得出这个值。因此,迭代器可以用来存储无限大的序列,这样我们就不用把他一次性放在内存中,而只在需要的时候进行计算。所以,对于读取大文件或者无线集合,最好是使用迭代器。实际上,Python2的大多数函数都是返回列表等序列,而Python3都已经改进为返回迭代器。
Python的内置模块itertools就是用来操作迭代器的一个模块,包含的函数都是能够创建迭代器来用于for循环或者next()。其中函数主要可以分为三类,分别是无限迭代器,有限迭代器,组合迭代器。
无限迭代器(Infinite Iterators)
这些函数可以生成无限的迭代器,我们主要学习以下三个函数的用法。
count([start=0, step=1]) 接收两个可选整形参数,第一个指定了迭代开始的值,第二个指定了迭代的步长。此外,start参数默认为0,step参数默认为1,可以根据需要来把这两个指定为其它值,或者使用默认参数。
import itertools
for i in itertools.count(10,2):
print(i)
if i>20:
break
[Running] python -u "e:\pythonee\code\test.py"
10
12
14
16
18
20
22
cycle(iterable) 是用一个可迭代对象中的元素来创建一个迭代器,并且复制自己的值,一直无限的重复下去。
import itertools
for i in itertools.cycle("abcd"):
print(i) # 具有无限的输出,可以按ctrl+c来停止。
[Running] python -u "e:\pythonee\code\test.py"
a
b
c
d
a
b
c
d
a
b
repeat(elem [,n])是将一个元素重复n遍或者无穷多遍,并返回一个迭代器。
import itertools
for i in itertools.repeat("abcd",5):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
abcd
abcd
abcd
abcd
abcd
组合迭代器(Combinatoric Iterators)
组合操作包括排列,笛卡儿积,或者一些离散元素的选择,组合迭代器就是产生这样序列的迭代器。我们来看看这几个函数的用法。
product(*iterables, repeat=1) 得到的是可迭代对象的笛卡儿积,*iterables参数表示需要多个可迭代对象。这些可迭代对象之间的笛卡儿积,也可以使用for循环来实现,例如 product(A, B) 与 ((x,y) for x in A for y in B)就实现一样的功能。
import itertools
for i in itertools.product([1,2,3],[4,5,6]):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)
而 repeat 参数则表示这些可迭代序列重复的次数。例如 product(A, repeat=4) 与 product(A, A, A, A)实现的功能一样。
import itertools
for i in itertools.product('ab','cd',repeat = 2):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
('a', 'c', 'a', 'c')
('a', 'c', 'a', 'd')
('a', 'c', 'b', 'c')
('a', 'c', 'b', 'd')
('a', 'd', 'a', 'c')
('a', 'd', 'a', 'd')
('a', 'd', 'b', 'c')
('a', 'd', 'b', 'd')
('b', 'c', 'a', 'c')
('b', 'c', 'a', 'd')
('b', 'c', 'b', 'c')
('b', 'c', 'b', 'd')
('b', 'd', 'a', 'c')
('b', 'd', 'a', 'd')
('b', 'd', 'b', 'c')
('b', 'd', 'b', 'd')
permutations(iterable,r=None)返回的是可迭代元素中的一个排列组合,并且是按顺序返回的,且不包含重复的结果。
import itertools
for i in itertools.permutations('abc'):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')
当然,第 2 个参数默认为None,它表示的是返回元组(tuple) 的长度,我们来尝试一下传入第二个参数。
import itertools
for i in itertools.permutations('abc',2):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'c')
('c', 'a')
('c', 'b')
combinations(iterable,r) 返回的是可迭代对象所有的长度为 r 的子序列,注意这与前一个函数 permutation 不同,permutation 返回的是排列,而 combinations 返回的是组合。
import itertools
for i in itertools.combinations('1234',2):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
('1', '2')
('1', '3')
('1', '4')
('2', '3')
('2', '4')
('3', '4')
combinations_with_replacement(iterable, r) 返回一个可与自身重复的元素组合,用法类似于 combinations 。
import itertools
for i in itertools.combinations_with_replacement('1234',2):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
('1', '1')
('1', '2')
('1', '3')
('1', '4')
('2', '2')
('2', '3')
('2', '4')
('3', '3')
('3', '4')
('4', '4')
有限迭代器(Iterators Terminating on the Shortest Input Sequence)
这里的函数有十来个,主要为大家介绍其中几个常用的函数。
chain(*iterables) 可以把多个可迭代对象组合起来,形成一个更大的迭代器。
import itertools
for i in itertools.chain('good','bye'):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
g
o
o
d
b
y
e
groupby(iterable,key=None) 可以把相邻元素按照 key 函数分组,并返回相应的 key 和 groupby,如果key函数为 None,则只有相同的元素才能放在一组。
import itertools
for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):
print(list(group))
[Running] python -u "e:\pythonee\code\test.py"
['A', 'a', 'a']
['B', 'B', 'b']
['c', 'C']
['A', 'A', 'a']
accumulate(iterable [,func]) 可以计算出一个迭代器,这个迭代器是由特定的二元函数的累计结果生成的,如果不指定的话,默认函数为求和函数。
import itertools
for i in itertools.accumulate([0,1,0,1,1,2,3,5]):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
0
1
1
2
3
5
8
13
如果我们指定这个累计函数,则还能有不同的用法,例如,指定一个最大值函数,或者自己定义的函数。
import itertools
for i in itertools.accumulate([2,1,4,3,5],max):
print(i)
[Running] python -u "e:\pythonee\code\test.py"
2
2
4
4
5
好了,以上便是对 itertools 模块的详细的总结。
2. enumerate 详解
可遍历/可迭代的对象(如列表、字符串)
enumerate多用于在for循环中得到计数,利用它可以同时获得索引和值,即需要index和value值的时候可以使用enumerate
enumerate()返回的是一个enumerate对象
s = [1, 2, 3, 4, 5]
e = enumerate(s)
print(e)
输出结果:
<enumerate object at 0x000001631F79A828>
enumerate的使用:
例如:已知s = [1,2,3,4,5,6]
,要求输出:
0,1
1,2
2,3
3,4
4,5
5,6
则
s = [1, 2, 3, 4, 5]
e = enumerate(s)
for index, value in e:
print('%s, %s' % (index, value))
# 输出结果:
0, 1
1, 2
2, 3
3, 4
4, 5
s = [1, 2, 3, 4, 5]
从指定索引1开始
for index, value in enumerate(s, 1):
print('%s, %s' % (index, value))
输出结果:
1, 1
2, 2
3, 3
4, 4
5, 5
3.堆 heapq:用在前 K 个高频元素
这个模块提供了堆队列算法的实现,也称为优先队列算法。
堆是一个二叉树,它的每个父节点的值都只会小于或等于所有孩子节点(的值)。 它使用了数组来实现:从零开始计数,对于所有的 k ,都有 heap[k] <= heap[2*k+1]
和 heap[k] <= heap[2*k+2]
。 为了便于比较,不存在的元素被认为是无限大。 堆最有趣的特性在于最小的元素总是在根结点:heap[0]。
这个API与教材的堆算法实现有所不同,具体区别有两方面:(a)我们使用了从零开始的索引。这使得节点和其孩子节点索引之间的关系不太直观但更加适合,因为 Python 使用从零开始的索引。 (b)我们的 pop 方法返回最小的项而不是最大的项(这在教材中称为“最小堆”;而“最大堆”在教材中更为常见,因为它更适用于原地排序)。
基于这两方面,把堆看作原生的Python list也没什么奇怪的: heap[0] 表示最小的元素,同时 heap.sort() 维护了堆的不变性!
要创建一个堆,可以使用list来初始化为 [] ,或者你可以通过一个函数 heapify() ,来把一个list转换成堆。
定义了以下函数:
heap是list
import headpq
heapq.heappush(heap, item)
将 item 的值加入 heap 中,保持堆的不变性。
heapq.heappop(heap)
弹出并返回 heap 的最小的元素,保持堆的不变性。如果堆为空,抛出 IndexError 。使用 heap[0] ,可以只访问最小的元素而不弹出它。
heapq.heappushpop(heap, item)
将 item 放入堆中,然后弹出并返回 heap 的最小元素。该组合操作比先调用 heappush() 再调用 heappop() 运行起来更有效率。
heapq.heapify(x)
将list x 转换成堆,原地,线性时间内。
heapq.heapreplace(heap, item)
弹出并返回 heap 中最小的一项,同时推入新的 item。 堆的大小不变。 如果堆为空则引发 IndexError。
这个单步骤操作比 heappop() 加 heappush() 更高效,并且在使用固定大小的堆时更为适宜。 pop/push 组合总是会从堆中返回一个元素并将其替换为 item。
返回的值可能会比添加的 item 更大。 如果不希望如此,可考虑改用 heappushpop()。 它的 push/pop 组合会返回两个值中较小的一个,将较大的值留在堆中。
该模块还提供了三个基于堆的通用功能函数。
heapq.merge(*iterables, key=None, reverse=False)
将多个已排序的输入合并为一个已排序的输出(例如,合并来自多个日志文件的带时间戳的条目)。 返回已排序值的 iterator。
类似于 sorted(itertools.chain(*iterables)) 但返回一个可迭代对象,不会一次性地将数据全部放入内存,并假定每个输入流都是已排序的(从小到大)。
具有两个可选参数,它们都必须指定为关键字参数。
key 指定带有单个参数的 key function,用于从每个输入元素中提取比较键。 默认值为 None (直接比较元素)。
reverse 为一个布尔值。 如果设为 True,则输入元素将按比较结果逆序进行合并。 要达成与 sorted(itertools.chain(*iterables), reverse=True) 类似的行为,所有可迭代对象必须是已从大到小排序的。
在 3.5 版更改: 添加了可选的 key 和 reverse 形参。
heapq.nlargest(n, iterable, key=None)
从 iterable 所定义的数据集中返回前 n 个最大元素组成的列表。 如果提供了 key 则其应指定一个单参数的函数,用于从 iterable 的每个元素中提取比较键 (例如 key=str.lower)。 等价于: sorted(iterable, key=key, reverse=True)[:n]。
heapq.nsmallest(n, iterable, key=None)
从 iterable 所定义的数据集中返回前 n 个最小元素组成的列表。 如果提供了 key 则其应指定一个单参数的函数,用于从 iterable 的每个元素中提取比较键 (例如 key=str.lower)。 等价于: sorted(iterable, key=key)[:n]。
后两个函数在 n 值较小时性能最好。 对于更大的值,使用 sorted() 函数会更有效率。 此外,当 n==1 时,使用内置的 min() 和 max() 函数会更有效率。 如果需要重复使用这些函数,请考虑将可迭代对象转为真正的堆。
基本示例
堆排序 可以通过将所有值推入堆中然后每次弹出一个最小值项来实现。
>>>
>>> def heapsort(iterable):
... h = []
... for value in iterable:
... heappush(h, value)
... return [heappop(h) for i in range(len(h))]
...
>>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
这类似于 sorted(iterable),但与 sorted() 不同的是这个实现是不稳定的。
堆元素可以为元组。 这适用于将比较值(例如任务优先级)与跟踪的主记录进行赋值的场合:
>>>
>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
4. map(函数,列表) 详解
语法:
map(function, iterable, ...)
实例:
>>> def square(x) : # 计算平方数
return x ** 2
>>> map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
<map object at 0x100d3d550> # 返回迭代器
>>> list(map(square, [1,2,3,4,5])) # 使用 list() 转换为列表
[1, 4, 9, 16, 25]
>>> list(map(lambda x: x ** 2, [1, 2, 3, 4, 5])) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
5. sorted 如果第一个条件 相同 则按第二个条件排序
pp = [{'loca':2,'line':4},
{'loca':2,'line':3},
{'loca':1,'line':5},
{'loca':1,'line':3},
{'loca':3,'line':2},
{'loca':3,'line':4}]
# 如果 pp['loca'] 相同 则按照 x['line'] 排序
tt = sorted(pp,key=lambda x:(x['loca'],x['line']))
tt
Out[22]:
[{'loca': 1, 'line': 3},
{'loca': 1, 'line': 5},
{'loca': 2, 'line': 3},
{'loca': 2, 'line': 4},
{'loca': 3, 'line': 2},
{'loca': 3, 'line': 4}]
技巧!在lambda的参数前取符号可以规定排序顺序,取负号就是从大到小
实例:
>>>people = [[7,0],[7,2],[7,1],[5,0],[6,1],[5,2]]
>
>>>sorted(people,key=lambda x:(x[0],-x[1]))
[[5, 2], [5, 0], [6, 1], [7, 2], [7, 1], [7, 0]]
>>>sorted(people,key=lambda x:(-x[0],x[1]))
[[7, 0], [7, 1], [7, 2], [6, 1], [5, 0], [5, 2]]
>>>sorted(people,key=lambda x:(-x[0],-x[1]))
[[7, 2], [7, 1], [7, 0], [6, 1], [5, 2], [5, 0]]
6. join方法:列表变字符串
语法:
str.join(sequence)
实例:
>>>print("-".join(['a','b','c']))
a-b-c
7. 几种COPY方式
在代码中不注意变量地址会闹出好多笑话,此时就需要copy变量
如果是list可以直接用全切片
a=[1,2,3]
b=a[:]
别的方式:可变类型共用的是同一个(里面的内容改变,到那时地址是不会改变) 不可变类型从一开始地址就发生了变化,之后的修改也是互不影响copy() 或者copy().copy()
主要理解内存地址
拷贝:其实就是将容器内数据,备份一份到新的地址
浅拷贝:可变类型共用的是同一个(里面的内容改变,到那时地址是不会改变)不可变类型一开始是共用的,但是如果发生改变地址就会发生改变.
深拷贝:deepcopy()
可变类型共用的是同一个(里面的内容改变,到那时地址是不会改变)
不可变类型从一开始地址就发生了变化,之后的修改也是互不影响
8. 进制转换
(1)十进制转其他
def fun(num,ind): #num是十进制数 ind是进制数
l=[]
while num!=0:
l.insert(0,str(num%ind))
num=num//ind
return ''.join(l)
常用公式:
十进制转二进制:bin(10)
十进制转八进制:oct(10)
十进制转十六进制:hex(10)
注意以上输出类型均为字符串,另外如果想去掉进制前缀可以使用切片方法
由于不同编译环境中转换为16进制后,16进制中的字母可能用小写或者大写表示,如果和需要的表示有出入,可以用ord()函数先将字母转换为ASCLL编号,再根据大小写编号大小关系加上32或者减去32,转为小写或者大写对应的字母编号,最后通过chr()函数将编号转换为字母
(2)其他进制转十进制
使用int(“String”,num)解决,string为其他进制的表示,num为该进制具体进制数。如下:
二进制转十进制:int("1010",2)
八进制转十进制:int("0o12",8)
十六进制转十进制:int("0xa",16)
可以带前缀,也可以不带
(3)需要十进制中转的进制转换
该转换根据以上两种转换可以很容易得出,思路均是使用十进制中转。如下:
二转八:二转十,再转八——oct(int("1010",2))
八转十六:八转十,再转十六——hex(int("12",8))
方法相同不过多展示
9. 匿名函数lambda 详解
例一,语法
函数写法:
def detail(x,y):
return x*y
变成lambda:
s = lambda x,y:x*y
print(s(3,3))
例二,lambda 关键词辅助对二维列表进行排序
假设有一个学生列表存储了学号,姓名,年龄信息:
students = [[3,'Jack',12],[2,'Rose',13],[1,'Tom',10],[5,'Sam',12],[4,'Joy',8]]
按学号顺序排序:
sorted(students,key=(lambda x:x[0]))
[[1, 'Tom', 10], [2, 'Rose', 13], [3, 'Jack', 12], [4, 'Joy', 8], [5, 'Sam', 12]]
按年龄倒序排序:
sorted(students,key=(lambda x:x[2]),reverse=True)
[[2, 'Rose', 13], [3, 'Jack', 12], [5, 'Sam', 12], [1, 'Tom', 10], [4, 'Joy', 8]]
10.小数转分数:fractions
from fractions import Fraction
Fraction(1,2)=1/2
11.GCD和LCM:最大公约数 最小公倍数
Greatest Common Divisor:最大公约数
法一:
import math
math.gcd(num1,num2)
法二:
def gcd(num1,num2):
return num==0?num1:gcd(num2,num1%num2)
Least Common Multiple:最小公倍数
法一:
import math
math.lcm(num1,num2)
法二:
def lcm(num1,num2):
return num1/gcd(num1,num2)*num2
12.字符串以及数字格式化详解(前后补零)
字符串补零:
n = "123"
s = n.zfill(5)
# s == '00123'
甚至可以是负数,数字还可以是字母:
n = "-abc"
s = n.zfill(5)
# s=-0abc
整型:用格式化%
n = 123
s = '%05d' % n
# s=00123
浮点型:
n = 3.14
s = '%.5f' % n
# s=3.14000
再看看:python 格式化输出详解(占位符:%、format、f表达式)——上篇 理论篇
13.几种取整
Python 几种取整的方法
数据处理是编程中不可避免的,很多时候都需要根据需求把获取到的数据进行处理,取整则是最基本的数据处理。取整的方式则包括向下取整、四舍五入、向上取整等等。
1、向下取整
向下取整直接用内建的 int() 函数即可:
>>> a = 3.75
>>> int(a)
3
2、四舍五入
对数字进行四舍五入用 round() 函数:
>>> round(3.25); round(4.85)
3.0
5.0
3、向上取整
向上取整需要用到 math 模块中的 ceil() 方法:
>>> import math
>>> math.ceil(3.25)
4.0
>>> math.ceil(3.75)
4.0
>>> math.ceil(4.85)
5.0
4、分别取整数部分和小数部分
有时候我们可能需要分别获取整数部分和小数部分,这时可以用 math 模块中的 modf() 方法,该方法返回一个包含小数部分和整数部分的元组:
>>> import math
>>> math.modf(3.25)
(0.25, 3.0)
>>> math.modf(3.75)
(0.75, 3.0)
>>> math.modf(4.2)
(0.20000000000000018, 4.0)
14.BFS迭代法:二叉树的层序遍历模板
二叉树的层序遍历几乎覆盖了二叉树题目的一半题目,但每次写起来都很模糊,代码却都能读懂。而比起回溯,我总宁愿用迭代。
若二叉树为:
用迭代法进行层序遍历:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def kthLargestLevelSum(self, root: Optional[TreeNode], k: int) -> int:
que=deque([root])
res=[]
while que:
path=[] #记录每层的变量列表
size=len(que) #记录每层的节点数量
for _ in range(size):
cur=que.popleft()
path.append(cur.val)
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
res.append(path)
return res
15.print()详解
语法
以下是 print() 方法的语法:
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
参数
objects
– 复数,表示可以一次输出多个对象。输出多个对象时,需要用 , 分隔。
sep
– 用来间隔多个对象,默认值是一个空格。
end
– 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串。
file
– 要写入的文件对象。
flush
– 输出是否被缓存通常决定于 file,但如果 flush 关键字参数为 True,流会被强制刷新。
返回值
无。
实例
以下展示了使用 print 函数的实例:
Python3 下测试
>>>print(1)
1
>>> print("Hello World")
Hello World
>>> a = 1
>>> b = 'runoob'
>>> print(a,b)
1 runoob
>>> print("aaa""bbb")
aaabbb
>>> print("aaa","bbb")
aaa bbb
>>>
>>> print("www","runoob","com",sep=".") # 设置间隔符
www.runoob.com
使用 flush 参数生成一个 Loading 的效果:
实例
import time
print("---RUNOOB EXAMPLE : Loading 效果---")
print("Loading",end = "")
for i in range(20):
print(".",end = '',flush = True)
time.sleep(0.5)
效果如下图:
16.科学计数法
x = 1e+3
x1 = 1e+03
x2 = 1e+003
x3 = 1E+3
x4 = 1E-3
print(x)
print(x1)
print(x2)
print(x3)
print(x4)
"""
1000.0
1000.0
1000.0
1000.0
0.001
"""
+3
与+03
与+003
是完全一致的。但是通常我们使用比较标准的写法E+03
来表示10^3
17.Counter:统计容器中各元素的个数并返回成字典
从可迭代对象中实例化 Counter
from collections import Counter
b = Counter("chenkc") # string
b2 = Counter(['c', 'h', 'e', 'n', 'k', 'c']) # list
b3 = Counter(('c', 'h', 'e', 'n', 'k', 'c')) # tuple
>>> print(b)
Counter({'c': 2, 'h': 1, 'e': 1, 'n': 1, 'k': 1})
>>> print(b2)
Counter({'c': 2, 'h': 1, 'e': 1, 'n': 1, 'k': 1})
>>> print(b3)
Counter({'c': 2, 'h': 1, 'e': 1, 'n': 1, 'k': 1})
实例化元素为空的 Counter
from collections import Counter
a = Counter()
# 为 Counter 添加元素以及对应的 count 计数
a['a'] = 1
a['b'] = 2
a['c'] = 3
>>> print(a)
Counter({'c': 3, 'b': 2, 'a': 1})
18.ASCII码与字符相互转换
# 用户输入字符
c = input("请输入一个字符: ")
# 用户输入ASCII码,并将输入的数字转为整型
a = int(input("请输入一个ASCII码: "))
print( c + " 的ASCII 码为", ord(c))
print( a , " 对应的字符为", chr(a))
执行以上代码输出结果为:
请输入一个字符: a
请输入一个ASCII码: 101
a 的ASCII 码为 97
101 对应的字符为 e
19.zip()的使用
zip()
函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 *
号操作符,可以将元组解压为列表。
语法:zip([iterable, ...])
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 返回一个对象
>>> zipped
<zip object at 0x103abc288>
>>> list(zipped) # list() 转换为列表
[(1, 4), (2, 5), (3, 6)]
>>> list(zip(a,c)) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> a1, a2 = zip(*zip(a,b)) # 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式
>>> list(a1)
[1, 2, 3]
>>> list(a2)
[4, 5, 6]
20.字典的值为列表或字典
1、值为列表的构造方法
dic = {}
dic.setdefault(key,[]).append(value)
***********示例*********
>>dic.setdefault('a',[]).append(1)
>>dic.setdefault('a',[]).append(2)
>>dic
>>{'a': [1, 2]}
2、值为字典的构造方法
dic = {}
dic.setdefault(key,{})[value] =1
***********示例*********
>>dic.setdefault('b',{})['f']=1
>>dic.setdefault('b',{})['h']=1
>>dic.setdefault('b',{})['g']=1
>>dic
>>{'b': {'h': 1, 'g': 1, 'f': 1}}
21.集合运算
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # 这里演示的是去重功能
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # 快速判断元素是否在集合内
True
>>> 'crabgrass' in basket
False
>>> # 下面展示两个集合间的运算.
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b #差集 # 集合a中包含而集合b中不包含的元素
{'r', 'd', 'b'}
>>> a | b #并集 # 集合a或b中包含的所有元素
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b #交集 # 集合a和b中都包含了的元素
{'a', 'c'}
>>> a ^ b #异或 # 不同时包含于a和b的元素
{'r', 'd', 'b', 'm', 'z', 'l'}
22.最优复杂度 求质数
- 判断一个数是否能被比它小的数整除
- 当一个数不是质数时,必定存在两个约数,一个大于等于sqrt(n),另一个小于sqrt(n)。利用这种特性,可以对1进行改进,只判断数n能否被小于sqrt(n)的数整除
- 质数一定是奇数,利用这个特点对2进行改进,判断数n能否被小于sqrt(n)的奇数整除
- 质数的分布具有特点,经过证明可以得到,(大于等于5的)质数一定和6的倍数相邻,一定是6x-1或6x+1。利用这种特性可以对整数进行筛选,只判断那些是6x-1或6x+1的整数是否为质数
证明过程如下:
令x≥1,将大于等于5的自然数表示如下: ······6x-2,6x-1,6x,6x+1,6x+2,6x+3,6x+4······
在以上的数字中,6x、6x+2和6x+4是偶数,一定不是质数;6x+3可以分解为3(2x+1),不是质数,因此质数只能是6x-1和6x+1
from math import sqrt
def isPirme(n):
if(n<=3):
return n>1
if(n%6!=1 and n%6!=5):
return False
for i in range(5,int(sqrt(n))+1,6):
if (n%i==0 or n%(i+2)==0):
return False
return True
还有一个埃氏筛法也挺好用,戳那直达
23.处理日期类题目的无敌工具datetime
链接一定要看看
datetime模块中包含如下类:
类名 | 功能说明 |
---|---|
date | 日期对象,常用的属性:year、 month、 day |
time | 时间对象:时、分、秒、微秒 |
datetime | 日期时间对象,常用的属性:hour、 minute、 second、 microsecond |
datetime_CAPI | 日期时间对象C语言接口 |
timedelta | 两个时间点之间的各种计算 |
tzinfo | 时区信息对象 |
24.幂的代替:左右移动位运算
1.左移运算符(<<)
定义:将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
设 a=1010 1110,a = a<< 2 将a的二进制位左移2位、右补0,即得a=1011 1000。
若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。
2.右移运算符(>>)
定义:将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。
例如:a=a>>2 将a的二进制位右移2位,左补0 或者 左补1得看被移数是正还是负。
操作数每右移一位,相当于该数除以2。
25.BFS遍历:迷宫 模板
例题:2019省赛【蓝桥OJ:BFS】
解析:【蓝桥OJ:BFS】2019省赛:迷宫 python实现
模板:
from collections import deque
#一大个可能需要格式化的地图
plat=""" ...
...
...
"""
#可能需要一个vis矩阵记录走过的位置
vis=[[False for i in j ]for j in plat]
#规定遍历方向:上左下右
dire=[(-1,0),(0,-1),(1,0),(0,1)]
#BFS过程:
run=collections.deque((0,0)) #run队列储存临时
while len(run)!=0: #某种循环条件来遍历地图
pop=run.popleft() #出队
x,y=pop[0],pop[1]
vis=... #vis来记录踩过的点
for d in dire:#每一次遍历就是一个方向
newx=x+d[0]
newy=y+d[1]
#判断要走的点是否符合某些条件(一定有边界条件)
if ......:
#如果新点可以走
run.append((newx,newy)) #新点入队
...#某些操作
OVER
26.读取txt文件
有时候蓝桥会把数据放在txt里,如果记不得怎么读取就寄了
with open("文件名.txt", "r", encoding='utf-8') as f: #打开文本
data = f.read() #读取文本
print(data)
此时data
是一个type为str的大字符串
仔细一些可以看这篇https://blog.csdn.net/weixin_40973138/article/details/106209020