用python刷算法的好用函数

2025/4/27978 字

引言

这几天用 python 刷 LeetCode,也第一次知道了一些好用的工具函数这里记录一下,免得后面忘了不好找。

数组操作函数

1. Counter计数器

python
from 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()函数

python
from 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]
python
from 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

python
num = 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. 堆

python
from 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. 二分查找

python
from 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. 缓存

python
from 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)

可以看到是碾压的速度

💬 评论区

写评论

暂无评论,来发表第一条吧。

© 2026 Corn 的自留地