article / aiznoyer
Python Base
语法基础
快读模板
python
import sys
input = lambda:sys.stdin.readline().strip()
内置排序算法 sorted()
可以对任何可迭代对象进行排序,返回一个新的排序后的列表。
sorted(iterable, key=None, reverse=False)
iterable:需要排序的可迭代对象
key:排序规则,可以传入一个函数,指定排序依据
reverse:是否反向排序,默认为False(升序)
python
word = ["apple", "banana", "kiwi", "cherry"]
print(sorted(words, key=len, reverse=True))
# 输出:['banana', 'cherry', 'apple', 'kiwi']
# 结合 lambda
print(sorted(words, key=lambda x: x[1]))
# 输出:['banana', 'cherry', 'kiwi', 'apple']
处理常见输入格式
python
# 1.单行多个整数
a, b, c = map(int, input().split()) # 输入:1 2 3
# 2.多行多个整数
n = int(input()) # 输入行数
lst = [int(input()) for _ in range(n)] # 读取 n 行整数
# 3.矩阵输入
n, m = map(int, input().split()) # 输入矩阵大小
matrix = [list(map(int, input().split())) for _ in range(n)] # 读取 n 行 m 列的矩阵
语法进阶
列表推导器
expression for item in iterable if condition
- expression: 表达式,用于生成列表中的元素
- item: 可迭代对象中的每个元素
- iterable: 可迭代对象(如列表、字符串、range等)
- condition: 可选,用于过滤元素的条件
python
# 过滤 1~20 中的偶数并取平方
evens = [i**2 for i in range(1, 21) if i % 2 == 0]
# 输出:[4, 16, 36, 64, 100, 144, 196, 256, 324, 400]
# 将输入字符串列表转换为整数列表
input_data = list(map(int, input().split())) # 假设输入 "1 2 3 4 5"
# 使用列表推导器实现
input_data = [int(x) for x in input().split()]
# 输出:[1, 2, 3, 4, 5]
# list(int) 转 int
num = int(''.join(map(str, nums)))
列表特性
比较大小的时候,不管长度如何,依次比较到第一个元素不相等的位置。比如 1, 2, 3 < 2, 3 因为在比较 1 < 2 的时候就终止。
range 函数
range(start, stop, step)
- start: 序列起始值(包含)
- stop: 序列结束值(不包含)
- step: 步长,默认为1
range返回的是一个range对象,是一个惰性序列,节省内存。如果需要列表,可以用list()函数将其转换为列表。
python
seq = range(10, 0, -1) # 倒序数组start应该是最大值,end应该是最小值
字符串
s1.startswith(s2, beg = 0, end = len(s2)): 用于检查字符串 s1 是否以字符串 s2 开头。是则返回 True。如果指定 beg 和 end,则在 s1 beg: end 范围内查找。
使用 ascii_lowercase 遍历 26 个字母:
python
from string import ascii_lowercase
cnt = {ch: 0 for ch in ascii_lowercase}
队列(先进先出)
python
from collections import deque
q = deque() # 初始化
q.append(x) # 从右侧入队
q.appendleft(x) # 从左侧入队
x = q.popleft() # 从左侧出队(O(1))
len(q) # 获取队列长度
q.extend(可迭代元素) # 向右侧添加可迭代元素
q.extendleft(可迭代元素)
q.count(1) # 统计元素个数 1
栈(先进后出)
python
stk = []
stk.append(x) # 入栈
stk.pop() # 出栈(默认弹出最后一个元素,O(1))
stk[-1] # 获取栈顶元素不移除
stk.get(key, default_value=None) # 返回 key 对应的 value,不存在则返回 default_value
stk.keys() # 键构成的可迭代对象
stk.values() # 值构成的可迭代对象
stk.items() # 键值对构成的可迭代对象
stk = defaultdict(list) # 指定了具有默认值空列表的字典
stk[key] = value # 创建一个键值对
栈与队列小技巧
- 快速判断空队列/栈:if not q: # 判空
- 栈的翻转:stack::-1 # 用切片获取逆序
- 队列转列表:list(q) # 将 deque 转换为普通列表
- 一次性初始化:deque(1, 2, 3) # 用迭代器初始化队列
map 映射函数
python
# map(function, iterable, ...)
# 计算平方数
def square(x):
return x ** 2
# 计算列表各个元素的平方
map(square, [1,2,3,4,5])
# [1, 4, 9, 16, 25]
# 使用 lambda 匿名函数
map(lambda x: x ** 2, [1, 2, 3, 4, 5])
# [1, 4, 9, 16, 25]
# 提供了两个列表,对相同位置的列表数据进行相加
map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
# [3, 7, 11, 15, 19]
库函数
Counter
python
from collections import Counter
list1 = ["a", "a", "a", "b", "c", "c", "f", "g", "g", "g", "f"]
dic = Counter(list1)
# dic = Counter({'a': 3, 'g': 3, 'c': 2, 'f': 2, 'b': 1})
list1 = ["a", "a", "a", "b", "c", "f", "g", "g", "c", "11", "g", "f", "10", "2"]
print(Counter(list1).most_common(3))
# 结果:[('a', 3), ('g', 3), ('c', 2)]
list1 = ["a", "a", "a", "b", "c", "f", "g", "g", "c", "11", "g", "f", "10", "2"]
print(Counter(list1).most_common(1))
# 结果:[('a', 3)]
# most_common(k) 时间复杂度 O(nlogk)。
bisect
bisect(a, x, lo = 0, hi = len(nums))
- 给定一个单调不减的数组 a,在其 [lo, hi) 区间中,返回第一个严格大于 x 的下标位置
- 时间复杂度 O(log n)
python
from bisect import *
# 0 1 2 3 4 5
arr = [1, 9, 9, 9, 200, 500]
# 查找插入位置
bisect(arr, 3) # 输出:1 (第一个大于 3 的索引)
bisect(arr, -99) # 输出:0 (第一个大于 -99 的索引)
bisect(arr, 1000) # 输出:6 (第一个大于 1000 的索引,此时为数组长度)
# 查找大于等于
# bisect(arr, x - 1)
# 逆序数组,找到小于 x 的位置索引
# arr = [-x for x in arr]
# bisect(arr, -x)
# 查找首个出现
# bisect_left(arr, x)
算法入门
埃氏筛(O(nloglogn))
求解素数
python
primes = []
is_prime = [True] * (n + 1)
is_prime[1] = is_prime[0] = False
for i in range(2, int(math.sqrt(n)) + 1): # i * i <= n
if is_prime[i]:
for j in range(i * i, n + 1, i):
is_prime[j] = False
for i in range(2, n + 1):
if is_prime[i]: primes.append(i)
逆波兰表达式
python
def eval_rpn(tokens: list[str]):
stack = []
ops = {
'+': lambda a, b: a + b,
'-': lambda a, b: a - b,
'*': lambda a, b: a * b,
'/': lambda a, b: int(a / b), # 向零取整(python默认向下取整)
}
for t in tokens:
if t in ops:
b = stack.pop()
a = stack.pop()
stack.append(ops[t](a, b)) # a 在前,b 在后
else:
stack.append(int(t))
return stack[0]
根据身高重建队列
python
def reconstructQueue(self, people: List[List[int]]):
# [7, 0],[4, 4],[7, 1],[5, 0],[6, 1],[5, 2]
people.sort(key=lambda x: (-x[0], x[1])) # 按照x[0]降序、x[1]升序排列
# [7, 0],[7, 1],[6, 1],[5, 0],[5, 2],[4, 4]
res = []
for i, p in enumerate(people):
h, k = p[0], p[1]
if k == i:
res.append(p)
elif k < i:
res.insert(k, p)
# [7, 0],[6, 1],[7, 1],[5, 0],[5, 2],[4, 4]
return res