用python刷算法的好用函数
2025/4/27978 字
引言
这几天用 python 刷 LeetCode,也第一次知道了一些好用的工具函数这里记录一下,免得后面忘了不好找。
数组操作函数
1. Counter计数器
pythonfrom collections import Counter
nums = [1, 1, 4, 5, 1, 4]
# Counter函数可以统计一个列表中元素的个数,通过返回字典的方式
count = Counter(nums)
print(count)
plaintext Counter({1: 3, 4: 2, 5: 1})
2. accumulate()函数 和 reduce()函数
pythonfrom itertools import accumulate
nums = [1, 2, 3, 4, 5]
# accumulate()函数可以得到一个可迭代对象累加后的迭代器
# 可以用来快速求前缀和
print(list(accumulate(nums)))
# 还可以自定义初始值,这样更符合使用习惯
print(list(accumulate(nums, initial=0)))
plaintext [1, 3, 6, 10, 15]
[0, 1, 3, 6, 10, 15]
pythonfrom functools import reduce
nums = [1, 2, 3, 4, 5]
# reduce() 可以自定义累积运算
print(reduce(lambda prev, next: prev + next, nums)) # 15
print(reduce(lambda prev, next: prev * next, nums)) # 120
15
120
3. 求数位和的骚操作 巧用str和map
pythonnum = 114514
print(sum(map(int,str(num))))
nums = [1, 11, 111, 1111, 11111, 111111]
print([sum(map(int,str(num))) for num in nums])
plaintext 16
[1, 2, 3, 4, 5, 6]
数据结构使用
1. 栈
python# list 可以直接当栈使用,因为有append和pop方法
stack = []
stack.append(1)
stack.append(2)
stack.append(3)
print(stack)
print(stack.pop())
print(stack)
plaintext [1, 2, 3]
3
[1, 2]
2. 堆
pythonfrom heapq import heappush, heappop, heapify
# 这个库可以把一个列表按照小顶堆的方式使用
nums = [4, 2, 7, 1, 5, 3]
heapify(nums)
print(nums) # [1, 2, 3, 4, 5, 7]
heappush(nums, -1)
print(nums) # [-1, 2, 1, 4, 5, 7, 3]
print(heappop(nums)) # -1
print(nums) # [1, 2, 3, 4, 5, 7]
plaintext [1, 2, 3, 4, 5, 7]
[-1, 2, 1, 4, 5, 7, 3]
-1
[1, 2, 3, 4, 5, 7]
python# 还可以通过重新 class 的 __lt__ (小于)方法来实现自定义类的小顶堆实现
class Stu:
def __init__(self, name, score):
self.name = name
self.score = score
def __lt__(self, other):
return self.score < other.score
stus = []
heappush(stus, Stu("A", 90))
heappush(stus, Stu("B", 100))
heappush(stus, Stu("C", 80))
print(heappop(stus).name) # C
print(heappop(stus).name) # A
print(heappop(stus).name) # B
plaintext C
A
B
3. 哈希表
python# python 中的字典实际上就是哈希表,有下面的方法可以用
cnt = {}
nums = [1, 1, 4, 5, 1, 4]
for num in nums:
cnt[num] = cnt.get(num, 0) + 1
print(cnt)
print(cnt.keys())
print(cnt.values())
for key, value in cnt.items():
print(key, value)
plaintext {1: 3, 4: 2, 5: 1}
dict_keys([1, 4, 5])
dict_values([3, 2, 1])
1 3
4 2
5 1
算法
1. 排序
python# 借用下上面的 Stu 类
stus = [Stu("Alice", 90), Stu("Bob", 85), Stu("Charlie", 95)]
stus.sort(key=lambda x: x.score)
print([stu.name for stu in stus])
plaintext ['Bob', 'Alice', 'Charlie']
2. 二分查找
pythonfrom bisect import bisect_left, bisect_right
nums = [1, 1, 4, 5]
# 如果能找到
# bisect_left 会返回对应元素的左边界的索引(包括该元素)
# bisect_right 会返回对应元素的右边界的索引(不包括该元素)
print(bisect_left(nums, 4)) # 2
print(bisect_right(nums, 4)) # 3
# 如果找不到
# bisect_left 会返回插入位置的索引
# bisect_right 也会返回插入位置的索引
print(bisect_left(nums, 3)) # 2
print(bisect_right(nums, 3)) # 2
# bisect两个方法还有 lo, hi参数,可以指定搜索范围 [lo, hi)
# 还有 key 参数,可以指定排序的依据
plaintext 2
3
2
2
辅助类工具
1. 缓存
pythonfrom line_profiler import profile # 测速工具
from functools import lru_cache
@profile
# 使用lru调度算法对函数建立缓存,如果之前已经计算过,则直接返回结果,否则重新计算。
# 可以自定义大小
@lru_cache(maxsize=None)
def fib_cached(n):
if n <= 1:
return n
return fib_cached(n-1) + fib_cached(n-2)
@profile
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
def test(n):
fib(n)
fib_cached(n)
python%reload_ext line_profiler
%lprun -f test test(20)
plaintext Timer unit: 1e-07 s Total time: 0.0245942 s
File: C:\Users\18499\AppData\Local\Temp\ipykernel_7240\2092348197.py
Function: test at line 19 Line # Hits Time Per Hit % Time Line Contents
==============================================================
19 def test(n):
20 1 244737.0 244737.0 99.5 fib(n)
21 1 1205.0 1205.0 0.5 fib_cached(n)
可以看到是碾压的速度
💬 评论区
暂无评论,来发表第一条吧。