Cheatsheet: Python

Last updated on April 1, 2026 am

本文整理了一些 Python 的常见语法及数据结构。

基础数据结构

List(列表)

  • 创建

    1
    2
    3
    4
    5
    lst = []                    # 空列表
    lst = [1, 2, 3, 4, 5]
    lst = list(range(5)) # [0, 1, 2, 3, 4]
    lst = [0] * 5 # [0, 0, 0, 0, 0]
    lst = [[0] * 3 for _ in range(2)] # [[0,0,0], [0,0,0]],正确创建二维列表
  • 访问与切片

    1
    2
    3
    4
    5
    6
    7
    8
    9
    lst = [1, 2, 3, 4, 5]

    lst[0] # 1,首元素
    lst[-1] # 5,末元素
    lst[1:3] # [2, 3],切片 [start:end),左闭右开
    lst[1:] # [2, 3, 4, 5]
    lst[:3] # [1, 2, 3]
    lst[::2] # [1, 3, 5],步长为 2
    lst[::-1] # [5, 4, 3, 2, 1],反转
  • 常用操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # 添加
    lst.append(x) # 尾部添加 $O(1)$
    lst.extend([6, 7]) # 追加多个元素 $O(k)$
    lst.insert(0, x) # 在位置 0 插入 $O(n)$

    # 删除
    lst.pop() # 删除并返回末尾元素 $O(1)$
    lst.pop(0) # 删除并返回首元素 $O(n)$
    lst.remove(x) # 删除第一个值为 x 的元素 $O(n)$
    del lst[0] # 删除索引 0 的元素
    del lst[1:3] # 删除切片
    lst.clear() # 清空

    # 查找
    lst.index(x) # x 第一次出现的索引,找不到抛异常 $O(n)$
    lst.count(x) # x 出现的次数 $O(n)$
    x in lst # 是否存在 $O(n)$

    # 其他
    len(lst) # 长度 $O(1)$
    lst.sort() # 原地排序 $O(n \log n)$
    lst.sort(reverse=True) # 降序排序
    lst.sort(key=lambda x: -x) # 自定义排序键
    sorted(lst) # 返回新排序列表,原列表不变
    lst.reverse() # 原地反转 $O(n)$
    reversed(lst) # 返回反转迭代器
    min(lst), max(lst), sum(lst)
  • 列表推导式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 基本形式
    squares = [x**2 for x in range(10)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

    # 带条件
    evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]

    # 多重循环
    pairs = [(x, y) for x in range(3) for y in range(3)]

    # 二维列表初始化(⚠️ 重要)
    # 错误方式:[[0]*3]*3 会创建引用相同的子列表
    # 正确方式:
    matrix = [[0 for _ in range(3)] for _ in range(3)]
  • 复杂度速查

    操作 复杂度 说明
    索引访问 O(1)O(1) lst[i]
    尾部添加 O(1)O(1) amortized append
    尾部删除 O(1)O(1) pop()
    头部插入/删除 O(n)O(n) insert(0), pop(0)
    查找 O(n)O(n) index, in
    排序 O(nlogn)O(n \log n) sort

Dict(字典)

  • 创建

    1
    2
    3
    4
    5
    6
    d = {}                      # 空字典
    d = dict() # 空字典
    d = {'a': 1, 'b': 2}
    d = dict(a=1, b=2)
    d = dict([('a', 1), ('b', 2)])
    d = {x: x**2 for x in range(5)} # 字典推导式 {0:0, 1:1, 2:4, 3:9, 4:16}
  • 访问与修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    d = {'a': 1, 'b': 2, 'c': 3}

    # 访问
    d['a'] # 1,不存在则抛 KeyError
    d.get('a') # 1,不存在返回 None
    d.get('a', 0) # 1,不存在返回默认值 0

    # 添加/修改
    d['d'] = 4 # 添加或修改
    d.update({'e': 5, 'f': 6}) # 批量更新
    d.setdefault('g', 7) # key 不存在则设置,返回 value

    # 删除
    del d['a'] # 删除,不存在抛 KeyError
    x = d.pop('b') # 删除并返回值,不存在抛 KeyError
    x = d.pop('b', None) # 删除,不存在返回默认值
    item = d.popitem() # 删除并返回 (key, value) 对,LIFO 顺序(Python 3.7+)
    d.clear() # 清空
  • 遍历

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    d = {'a': 1, 'b': 2, 'c': 3}

    for key in d: # 遍历 key
    print(key)

    for key in d.keys(): # 同上
    print(key)

    for value in d.values(): # 遍历 value
    print(value)

    for key, value in d.items(): # 遍历 (key, value)
    print(key, value)
  • 常用操作

    1
    2
    3
    4
    5
    6
    7
    len(d)                      # 键值对数量 $O(1)$
    'a' in d # 判断 key 是否存在 $O(1)$
    1 in d.values() # 判断 value 是否存在 $O(n)$

    # 合并字典(Python 3.9+)
    d3 = d1 | d2 # 合并为新字典
    d1 |= d2 # d1 更新为合并结果
  • OrderedDict(Python 3.7+ 普通 dict 也是有序的):

    1
    2
    3
    4
    5
    from collections import OrderedDict

    od = OrderedDict() # 有序字典
    od.move_to_end('key') # 移到末尾
    od.move_to_end('key', last=False) # 移到开头
  • 复杂度速查

    操作 平均 最坏
    访问/插入/删除 O(1)O(1) O(n)O(n)
    查找 key O(1)O(1) O(n)O(n)
    遍历 O(n)O(n) O(n)O(n)

Tuple(元组)

  • 特点:不可变序列,可作为 dict 的 key

  • 创建与使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    t = ()                      # 空元组
    t = (1,) # 单元素元组,逗号必须!
    t = (1, 2, 3)
    t = 1, 2, 3 # 括号可省略

    # 不可变
    # t[0] = 100 # TypeError

    # 解包
    a, b, c = (1, 2, 3)
    a, b = b, a # 交换变量
    first, *rest = (1, 2, 3, 4) # first=1, rest=[2,3,4]

    # 命名元组
    from collections import namedtuple
    Point = namedtuple('Point', ['x', 'y'])
    p = Point(1, 2)
    print(p.x, p.y) # 1 2

Set(集合)

  • 特点:无序、不重复元素集合

  • 创建

    1
    2
    3
    4
    s = set()                   # 空集合,不能用 {}(那是空字典)
    s = {1, 2, 3}
    s = set([1, 2, 2, 3]) # {1, 2, 3},自动去重
    s = {x for x in range(10) if x % 2 == 0} # 集合推导式
  • 操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    # 添加/删除
    s.add(4) # 添加元素 $O(1)$
    s.remove(4) # 删除,不存在抛 KeyError
    s.discard(4) # 删除,不存在不报错
    x = s.pop() # 随机删除并返回一个元素
    s.clear() # 清空

    # 集合运算(面试高频!)
    a = {1, 2, 3}
    b = {2, 3, 4}

    a | b # 并集 {1, 2, 3, 4}
    a & b # 交集 {2, 3}
    a - b # 差集 {1}
    a ^ b # 对称差集 {1, 4}

    a.union(b) # 并集,返回新集合
    a.intersection(b) # 交集
    a.difference(b) # 差集
    a.symmetric_difference(b) # 对称差集

    a.update(b) # a 更新为并集(原地修改)
    a.intersection_update(b) # a 更新为交集

    # 判断
    1 in s # 是否存在 $O(1)$
    a.issubset(b) # a 是否是 b 的子集
    a.issuperset(b) # a 是否是 b 的超集
    a.isdisjoint(b) # 是否不相交
  • 应用场景

    1
    2
    3
    4
    5
    6
    7
    8
    # 去重
    unique = list(set(lst))

    # 判断重复
    has_duplicate = len(lst) != len(set(lst))

    # 找两列表共同元素
    common = list(set(lst1) & set(lst2))
  • 复杂度速查

    操作 平均 最坏
    添加 O(1)O(1) O(n)O(n)
    删除 O(1)O(1) O(n)O(n)
    查找 O(1)O(1) O(n)O(n)
    并/交/差集 O(len(s)+len(t))O(len(s)+len(t)) -

Frozen Set(不可变集合)

1
2
fs = frozenset([1, 2, 3])       # 不可变,可作为 dict 的 key 或 set 的元素
# fs.add(4) # AttributeError

进阶数据结构(collections 模块)

deque(双端队列)

  • 特点:两端 O(1)O(1) 插入删除,适合队列/栈场景
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from collections import deque

# 创建
dq = deque() # 空双端队列
dq = deque([1, 2, 3])
dq = deque(maxlen=5) # 最大长度,满时添加会自动丢弃

# 两端操作(都是 $O(1)$)
dq.append(x) # 尾部添加
dq.appendleft(x) # 头部添加
dq.pop() # 尾部删除并返回
dq.popleft() # 头部删除并返回

# 其他操作
dq.rotate(1) # 向右旋转 1 位
dq.rotate(-1) # 向左旋转 1 位
dq.extend([4, 5]) # 尾部追加多个
dq.extendleft([0, -1]) # 头部追加多个(注意顺序)
len(dq), x in dq
  • vs list
    • deque 两端操作 O(1)O(1)list 头部操作 O(n)O(n)
    • deque 随机访问 O(n)O(n)listO(1)O(1)
    • 队列/栈场景优先用 deque

Counter(计数器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from collections import Counter

# 创建
c = Counter() # 空计数器
c = Counter(['a', 'b', 'a', 'c', 'a']) # Counter({'a': 3, 'b': 1, 'c': 1})
c = Counter({'a': 3, 'b': 1})
c = Counter(a=3, b=1)

# 访问
c['a'] # 3,不存在返回 0(不会抛异常)
c.most_common(2) # [('a', 3), ('b', 1)],最常见的 2 个

# 更新
c.update(['a', 'b']) # 增加计数
c.subtract(['a']) # 减少计数
c.clear()

# 运算
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2, c=3)
c1 + c2 # 相加(取并集,值相加)
c1 - c2 # 相减(只保留正值)
c1 & c2 # 交集(取最小值)
c1 | c2 # 并集(取最大值)

# 应用场景
text = "hello world"
char_count = Counter(text) # 统计字符频率
top3 = char_count.most_common(3)

defaultdict(默认字典)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from collections import defaultdict

# 创建
dd = defaultdict(int) # 默认值为 0
dd = defaultdict(list) # 默认值为 []
dd = defaultdict(set) # 默认值为 set()
dd = defaultdict(lambda: 'N/A') # 自定义默认值

# 使用
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4)]
d = defaultdict(list)
for k, v in s:
d[k].append(v) # 无需检查 key 是否存在
# d = {'yellow': [1, 3], 'blue': [2, 4]}

namedtuple(命名元组)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from collections import namedtuple

# 创建类
Point = namedtuple('Point', ['x', 'y'])
Point = namedtuple('Point', 'x y') # 也可空格分隔

# 实例化
p = Point(1, 2)
p = Point(x=1, y=2)

# 访问
p.x, p.y # 字段名访问,更清晰
p[0], p[1] # 索引访问也支持

# 方法
p._asdict() # 转为 OrderedDict {'x': 1, 'y': 2}
p._replace(x=3) # 创建新实例,x=3,y=2
Point._fields # ('x', 'y'),字段名元组

优先队列(堆)

Python 使用 heapq 模块实现最小堆。

heapq 基础(最小堆)

Python 的 heapq 模块实现的是最小堆(堆顶元素最小),用一个普通列表来存储堆结构。

核心概念

  • :特殊的完全二叉树,父节点 ≤ 子节点(最小堆)
  • 堆顶:列表的第 0 个元素 h[0],总是当前最小值
  • 列表存储:堆用列表模拟二叉树,对于索引 i
    • 左子节点索引 = 2*i + 1
    • 右子节点索引 = 2*i + 2
    • 父节点索引 = (i-1) // 2

完整使用流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import heapq

# ========== 方式 1:从空列表开始,逐个添加 ==========
h = [] # 创建一个空列表作为堆

# 入堆:heappush(堆列表, 要添加的元素)
heapq.heappush(h, 5) # h = [5]
heapq.heappush(h, 2) # h = [2, 5](2 上浮到堆顶)
heapq.heappush(h, 7) # h = [2, 5, 7]
heapq.heappush(h, 1) # h = [1, 2, 7, 5](1 上浮到堆顶)

print(h[0]) # 1,堆顶元素(最小值),O(1)

# 出堆:heappop(堆列表) → 返回最小值,并维护堆结构
min_val = heapq.heappop(h) # min_val = 1,h 变为 [2, 5, 7]
print(min_val) # 1

# ========== 方式 2:将已有列表转为堆 ==========
lst = [5, 2, 7, 1, 3]
heapq.heapify(lst) # 原地将列表转为堆,O(n)
# lst 现在变成 [1, 2, 7, 5, 3](满足堆性质,但不一定是排序好的)

# 此时可以像普通堆一样使用
print(lst[0]) # 1,最小值
heapq.heappush(lst, 0) # 添加 0,lst[0] 变成 0

常用操作速查

操作 函数 说明 复杂度
入堆 heapq.heappush(h, x) 添加元素 x,自动调整堆 O(logn)O(\log n)
出堆 heapq.heappop(h) 弹出并返回最小值 O(logn)O(\log n)
查看堆顶 h[0] 不移除,仅查看最小值 O(1)O(1)
列表转堆 heapq.heapify(lst) 原地转换已有列表 O(n)O(n)

组合操作(效率优化)

1
2
3
4
5
6
7
8
9
10
h = [1, 5, 3]  # 假设这是一个堆

# heappushpop:先 push 再 pop,比分开执行更高效
result = heapq.heappushpop(h, 2) # h 先添加 2,然后弹出最小值 1
# result = 1, h = [2, 5, 3]

# heapreplace:先 pop 再 push(⚠️ 堆不能为空!)
result = heapq.heapreplace(h, 4) # 先弹出最小值 2,再添加 4
# result = 2, h = [3, 5, 4]
# 等价于:先 heappop,再 heappush,但效率更高

最大堆实现(Python 技巧)

heapq 只提供最小堆,实现最大堆需要技巧:

方法 1:存入负值(最常用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import heapq

max_h = [] # 创建空堆

# 入堆时存负值
x = 5
heapq.heappush(max_h, -x) # 存 -5
heapq.heappush(max_h, -3) # 存 -3
heapq.heappush(max_h, -8) # 存 -8
# max_h = [-8, -5, -3](最小堆,但对应原数据的最大堆)

# 出堆时取负还原
max_val = -heapq.heappop(max_h) # -(-8) = 8,最大值
print(max_val) # 8

# 查看最大值(堆顶)
print(-max_h[0]) # 当前最大值

方法 2:封装成类(更清晰)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import heapq

class MaxHeap:
"""基于 heapq 的最大堆封装"""
def __init__(self):
self.data = [] # 内部存储负值

def push(self, x):
"""添加元素"""
heapq.heappush(self.data, -x)

def pop(self):
"""弹出最大值"""
return -heapq.heappop(self.data)

def top(self):
"""查看最大值(不移除)"""
return -self.data[0]

def empty(self):
"""是否为空"""
return len(self.data) == 0

def size(self):
"""元素个数"""
return len(self.data)

# 使用示例
mh = MaxHeap()
mh.push(5)
mh.push(2)
mh.push(8)
print(mh.top()) # 8
print(mh.pop()) # 8
print(mh.top()) # 5

高级用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 获取列表中 n 个最大/最小值
heapq.nlargest(3, lst) # 最大的 3 个,返回列表
heapq.nsmallest(3, lst) # 最小的 3 个

# 带 key 函数
heapq.nlargest(3, students, key=lambda s: s.score)

# TopK 问题(海量数据找前 K 大)
def top_k(nums, k):
"""找数组中前 k 大的元素"""
heap = []
for num in nums:
if len(heap) < k:
heapq.heappush(heap, num)
elif num > heap[0]: # 比堆顶大
heapq.heapreplace(heap, num)
return heap # 堆中是前 k 大(无序)

带优先级的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 方式 1:元组 (priority, value)
# 注意:如果 priority 相同,会比较 value,value 不可比较时会报错
pq = []
heapq.heappush(pq, (1, 'task1')) # priority=1
heapq.heappush(pq, (0, 'task2')) # priority=0,优先执行

# 方式 2:使用计数器打破平手(推荐)
counter = 0
pq = []
heapq.heappush(pq, (1, counter, 'task1'))
counter += 1
heapq.heappush(pq, (1, counter, 'task2')) # 同优先级时,先加入的先出

# 方式 3:自定义类,实现 __lt__
class Task:
def __init__(self, priority, name):
self.priority = priority
self.name = name
def __lt__(self, other):
return self.priority < other.priority

pq = []
heapq.heappush(pq, Task(1, 'A'))

其他常用技巧

字符串操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 基本操作
s = "Hello World"
s.upper(), s.lower() # 大小写转换
s.startswith("He"), s.endswith("ld") # 判断开头/结尾
s.find("l") # 2,第一次出现的索引,找不到返回 -1
s.rfind("l") # 9,最后一次出现
s.count("l") # 3,计数
s.replace("l", "L") # "HeLLo WorLd"
s.strip(), s.lstrip(), s.rstrip() # 去除空白

# 分割与合并
s.split() # ['Hello', 'World'],默认按空白分割
"1,2,3".split(",") # ['1', '2', '3']
"-".join(['a', 'b', 'c']) # "a-b-c"

# 判断
"123".isdigit() # True
"abc".isalpha() # True
"abc123".isalnum() # True
" ".isspace() # True

# f-string(Python 3.6+)
name = "Alice"
age = 20
f"My name is {name}, age {age}" # 格式化字符串
f"Pi = {3.14159:.2f}" # Pi = 3.14,格式控制

列表/字典常用技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 枚举 enumerate
for i, x in enumerate(lst): # (0, lst[0]), (1, lst[1])...
print(i, x)
for i, x in enumerate(lst, 1): # 从 1 开始计数
print(i, x)

# zip 并行遍历
names = ['Alice', 'Bob']
ages = [20, 25]
for name, age in zip(names, ages):
print(name, age)

# 解包
list(zip(*matrix)) # 矩阵转置

# 排序 key 函数
sorted(lst, key=lambda x: -x) # 降序
sorted(lst, key=len) # 按长度排序
sorted(dict.items(), key=lambda x: x[1]) # 按 value 排序

# 列表去重并保持顺序
dedup = list(dict.fromkeys(lst))

# 扁平化二维列表
flat = [x for row in matrix for x in row]

# 批量赋值
a, b, c = [1, 2, 3]
*a, b = [1, 2, 3, 4] # a=[1,2,3], b=4

面试高频模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# 1. 两数之和(dict 做 hash)
def two_sum(nums, target):
seen = {}
for i, x in enumerate(nums):
if target - x in seen:
return [seen[target-x], i]
seen[x] = i

# 2. 滑动窗口(用 Counter 统计)
from collections import Counter

def sliding_window(s, t):
need = Counter(t)
window = Counter()
valid = 0

left = right = 0
while right < len(s):
c = s[right]
right += 1
# 扩大窗口
if c in need:
window[c] += 1
if window[c] == need[c]:
valid += 1

# 收缩窗口
while valid == len(need):
# 更新结果
if right - left < min_len:
min_len = right - left
start = left
d = s[left]
left += 1
if d in need:
if window[d] == need[d]:
valid -= 1
window[d] -= 1

# 3. 并查集(dict 实现)
class UnionFind:
def __init__(self):
self.parent = {}
def find(self, x):
if x not in self.parent:
self.parent[x] = x
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # 路径压缩
return self.parent[x]
def union(self, x, y):
px, py = self.find(x), self.find(y)
if px != py:
self.parent[px] = py

# 4. LRU Cache(OrderedDict)
from collections import OrderedDict

class LRUCache:
def __init__(self, capacity):
self.cache = OrderedDict()
self.capacity = capacity

def get(self, key):
if key not in self.cache:
return -1
self.cache.move_to_end(key) # 移到最新
return self.cache[key]

def put(self, key, value):
if key in self.cache:
self.cache.move_to_end(key)
self.cache[key] = value
if len(self.cache) > self.capacity:
self.cache.popitem(last=False) # 删除最旧的

Cheatsheet: Python
https://cny123222.github.io/2026/03/31/Cheatsheet-Python/
Author
Nuoyan Chen
Posted on
March 31, 2026
Licensed under