文章目录
1. 处理输入
[list/tuple/dict(input().split()) for _ range(N)] # 对应有N行输入
map(int, input().split()) # 批量转换成int
2. 经典题目
计算器
3. 常用函数方法
3.1 列表推导式
new_list = [expression for item in iterable if condition]
- expression 是对每个元素执行的操作。
- item 是迭代中的当前项。
- iterable 是可迭代对象,如列表、元组、字符串等。
- if condition 是可选的过滤条件。
a.基本用法
squares = [x**2 for x in range(10)]
print(squares) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
b.带条件的列表推导式
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # 输出: [0, 4, 16, 36, 64]
c.嵌套列表推导式
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
flattened_matrix = [num for row in matrix for num in row]
print(flattened_matrix) # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
d.复杂表达式
words = ['apple', 'banana', 'cherry']
word_lengths = [(word, len(word)) for word in words]
print(word_lengths) # 输出: [('apple', 5), ('banana', 6), ('cherry', 6)]
3.2 .sort() / sorted() 的 key
a.字符串列表按长度排序
words = ['banana', 'pie', 'apple', 'cherry']
words.sort(key=len)
print(words) # 输出: ['pie', 'apple', 'banana', 'cherry']
b.字典列表按照特定键排序
people = [
{'name': 'Alice', 'age': 30},
{'name': 'Bob', 'age': 25},
{'name': 'Charlie', 'age': 35}
]
# 按年龄升序排列
people.sort(key=lambda person: person['age'])
print(people)
# 输出:
# [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
c.使用itemgetter进行排序
当需要根据多个字段进行排序时,可以使用operator.itemgetter,它比lambda函数更高效。
from operator import itemgetter
people = [
{'name': 'Alice', 'age': 30, 'height': 165},
{'name': 'Bob', 'age': 25, 'height': 175},
{'name': 'Charlie', 'age': 30, 'height': 180}
]
# 先按年龄,再按身高排序
people.sort(key=itemgetter('age', 'height'))
print(people)
# 输出:
# [{'name': 'Bob', 'age': 25, 'height': 175}, {'name': 'Alice', 'age': 30, 'height': 165}, {'name': 'Charlie', 'age': 30, 'height': 180}]
3.3 .is[ anything ] ()函数
.isdigit():检查是否只包含数字.isalpha():检查是否只包含字母.isupper():检查是否只包含大写字母.islower():检查是否只包含小写字母.isalnum():检查是否只包含字母或数字.lower():将字符串中的所有大写字母转换为小写字母。.upper():将字符串中的所有小写字母转换为大写字母
3.4 chr() / ord()
3.5 divmod()
4 常用算法
4.1 二分查找
def binary_search(nums, target):
left = 0
right = len(nums) - 1 # 初始化右边界为数组最后一个索引
while left <= right: # 循环条件:当 left 小于等于 right 时继续循环
mid = (left + right) // 2 # 计算中间位置
if nums[mid] == target:
return mid # 找到目标值,返回其索引
elif nums[mid] < target:
left = mid + 1 # 目标值在右半部分
else:
right = mid - 1 # 目标值在左半部分
return -1 # 如果没有找到目标值,返回 -1
4.2 矩阵4个方向扩散
while stack:
x, y = stack.pop()
if -1 < x < m and -1 < y < n and not visited[x][y] and digit_sum(x) + digit_sum(y) <= k:
visited[x][y] = True
ans += 1
stack.extend([(x-1, y), (x+1, y), (x, y-1), (x, y+1)])
4.3 visited数组表示有无访问
4.4 哈夫曼树
5 常用数据结构的实现
5.1 树
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val # 节点存储的值
self.left = left # 左子节点
self.right = right # 右子节点
# 二叉树还可以通过数组的方式存储
tree = [0] * n # 将此二叉树存放入数组tree当中,有如下的关系:
tree[0] = root # 根节点存放在array[0]中
tree[i] = i
tree[2*i + 1] = i.left # 左孩子存放在tree[2*i+1]
tree[2*i + 2] = i.right # 右孩子存放在Array[2*i+2]
tree[i-1 //2] = i.father # 节点i的父节点将位于索引 (i - 1) / 2的位置(如果i不是根节点)。
5.2 链表
class ListNode:
def __init__(self, value=0, next=None):
self.value = value # 节点存储的值
self.next = next # 指向下一个节点的指针
6 装饰器
装饰器(Decorator)是 Python 中一种强大的语法特性,它允许你在不修改原函数代码的前提下,动态地为函数或方法添加新的功能。其本质是一个接收函数作为参数并返回一个新函数的可调用对象(通常是函数或类)。
6.1 简单装饰器示例
def my_decorator(func):
def wrapper(*args, **kwargs):
print("装饰器:函数执行前的操作")
result = func(*args, **kwargs) # 调用原函数
print("装饰器:函数执行后的操作")
return result
return wrapper
@my_decorator
def say_hello(name):
print(f"Hello, {name}!")
# 调用被装饰的函数
say_hello("Alice")
# 输出:
# 装饰器:函数执行前的操作
# Hello, Alice!
# 装饰器:函数执行后的操作
func: 被装饰的原始函数。wrapper: 装饰器内部定义的嵌套函数,它“包装”了对func的调用。wrapper函数接收*args和**kwargs,确保它可以接受任意数量和类型的参数,从而适配任何被装饰的函数。返回wrapper: 装饰器函数必须返回wrapper(或其他可调用对象),这样当调用原函数名时,实际执行的是wrapper。
6.2 带参数的装饰器
有时需要向装饰器本身传递参数,这需要在原有装饰器结构外再嵌套一层函数。
def repeat(times):
"""一个带参数的装饰器:重复执行函数指定次数"""
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result # 返回最后一次执行的结果
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hi, {name}!")
greet("Bob")
# 输出:
# Hi, Bob!
# Hi, Bob!
# Hi, Bob!
repeat(times): 最外层函数,接收装饰器的参数timesdecorator(func): 中间层函数,接收被装饰的函数funcwrapper(*args, **kwargs): 最内层函数,执行核心逻辑(重复调用func)。
6.3 functools.wraps 保持元信息
直接使用 wrapper 会丢失原函数的元信息(如 __name__, __doc__)。使用functools.wraps可以解决此问题。
from functools import wraps
def timing_decorator(func):
@wraps(func) # 保留原函数的元数据
def wrapper(*args, **kwargs):
import time
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行耗时: {end - start:.4f} 秒")
return result
return wrapper
@timing_decorator
def slow_function():
"""一个模拟耗时的函数"""
time.sleep(1)
return "Done"
print(slow_function.__name__) # 输出: slow_function (而不是 wrapper)
print(slow_function.__doc__) # 输出: 一个模拟耗时的函数
slow_function() # 输出执行耗时
6.4 常用装饰器示例
6.4.1 记忆化 (@cache)
如前所述,@functools.cache 可以缓存函数结果,避免重复计算。
import functools
@functools.cache
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 第一次计算
print(fibonacci(10)) # 直接从缓存获取,极快
实际实现,用一个哈希表存储入参和对应的结果,以空间换时间
6.4.2 类装饰器
装饰器也可以是类。类需要实现 __call__ 方法使其可调用。
class CountCalls:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"{self.func.__name__} 已被调用 {self.count} 次")
return self.func(*args, **kwargs)
@CountCalls
def say_hi():
print("Hi!")
say_hi() # 输出: say_hi 已被调用 1 次
say_hi() # 输出: say_hi 已被调用 2 次
3490

被折叠的 条评论
为什么被折叠?



