【蓝桥小册】【Python算法竞赛工具笔记】长更

在这里插入图片描述
蓝桥国三
日常训练时的万字整理
涵盖了比赛能用的很多技巧

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:统计容器中各元素的个数并返回成字典

详解Python计数的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.字典的值为列表或字典

Python字典中的值为列表或字典的构造方法

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.最优复杂度 求质数

  1. 判断一个数是否能被比它小的数整除
  2. 当一个数不是质数时,必定存在两个约数,一个大于等于sqrt(n),另一个小于sqrt(n)。利用这种特性,可以对1进行改进,只判断数n能否被小于sqrt(n)的数整除
  3. 质数一定是奇数,利用这个特点对2进行改进,判断数n能否被小于sqrt(n)的奇数整除
  4. 质数的分布具有特点,经过证明可以得到,(大于等于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

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤米尼克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值