python 赋值 max_int:¶
import sys
inf = sys.maxsize
lambda 表达式¶
list.sort(key=lambda x : x[2])
words = ['apple', 'banana', 'kiwi', 'pear']
words.sort(key=len)
chars = ['a', 'B', 'c', 'A']
chars.sort(key=str.lower())
def my_logic(x):
return (x %2 != 0, x)
nums = [4, 1, 3, 2, 5, 6]
nums.sort(key=my_logic)
print 保留两位小数输出:¶
pi = 3.1415926
print(f"数值是: {pi:.2f}")
# 输出: 数值是: 3.14
python 实现优先队列¶
在 Python 中,实现优先队列(Priority Queue)最常用、最高效的方法是使用 heapq 模块。
heapq 实现的是一个 最小堆(Min-Heap),即:每次弹出的都是队列中最小的元素。
1. 使用 heapq 模块(最推荐,算法常用)¶
heapq 并不是一个独立的类,而是一组操作 列表(List) 的函数。
核心操作:¶
import heapq
# 1. 创建一个空列表作为堆
pq = []
# 2. 入队 (Push) - O(log n)
heapq.heappush(pq, 10)
heapq.heappush(pq, 5)
heapq.heappush(pq, 20)
heapq.heappush(pq, 1)
# 3. 出队 (Pop) - 弹出最小值 - O(log n)
smallest = heapq.heappop(pq)
print(smallest) # 输出: 1
# 4. 查看最小值(不弹出) - O(1)
print(pq[0]) # 输出: 5
# 5. 将现有列表转化为堆 - O(n)
nums = [3, 1, 4, 1, 5]
heapq.heapify(nums)
2. 如何实现“最大堆”(Max-Heap)?¶
Python 的 heapq 默认只有最小堆。如果你想让 最大的元素先出队,通用的技巧是:将所有数值取负号。
import heapq
max_pq = []
nums = [10, 5, 20, 1]
for n in nums:
heapq.heappush(max_pq, -n) # 存入负数
# 弹出时再取反
largest = -heapq.heappop(max_pq)
print(largest) # 输出: 20
3. 存储复杂对象(优先级 + 数据)¶
在算法题(如 Dijkstra 或 任务调度)中,通常需要存储 (优先级, 数据) 这样的元组。heapq 会默认根据 元组的第一个元素 进行排序。
import heapq
pq = []
# 格式:(优先级数字, 任务名称)
# 数字越小,优先级越高
heapq.heappush(pq, (3, "写作业"))
heapq.heappush(pq, (1, "吃午饭"))
heapq.heappush(pq, (2, "看电影"))
# 弹出优先级最高的任务
priority, task = heapq.heappop(pq)
print(f"当前任务: {task} (优先级: {priority})")
# 输出: 当前任务: 吃午饭 (优先级: 1)
4. 使用 queue.PriorityQueue(线程安全)¶
如果你在写 多线程程序,应该使用 queue 模块中的 PriorityQueue 类。它是基于 heapq 封装的,但是 线程安全 的。
from queue import PriorityQueue
q = PriorityQueue()
q.put((2, "中等优先级"))
q.put((1, "高优先级"))
q.put((3, "低优先级"))
# get() 会阻塞直到有数据
print(q.get()) # 输出: (1, '高优先级')
5. 性能对比与总结¶
| 特性 | heapq (推荐) |
queue.PriorityQueue |
|---|---|---|
| 底层实现 | 列表 (List) | 列表 + 锁 (Lock) |
| 线程安全 | 否 | 是 |
| 运行速度 | 快 (开销极小) | 慢 (因为有锁) |
| 适用场景 | 算法竞赛、LeetCode、常规开发 | 多线程并发任务调度 |
算法题建议: 始终使用 heapq。它更轻量,速度更快。记住:heappush 和 heappop 都是 \(O(\log n)\) 的复杂度。