当前位置:首页>python>Python 数据结构的高级玩法,面试官听了都点头

Python 数据结构的高级玩法,面试官听了都点头

  • 2026-10-11 06:01:56
Python 数据结构的高级玩法,面试官听了都点头
七八层 if-else 嵌套、好几个临时列表来回倒腾数据、为了统计几个元素还手动维护了一个计数器字典……
很多代码之所以又长又丑又慢,不是因为需求复杂,而是因为对 Python 内置数据结构不熟悉。

1. 用 dict.get 提供默认值

很多教程会教你这么写:

config = {'host': 'localhost'}if 'port' in config:    port = config['port']else:    port = 8080

试试这个:

config = {'host': 'localhost'}port = config.get('port', 8080)print(port)  # 8080

dict.get(key, default) 在键不存在时返回默认值而不是抛 KeyError,一行代码替代 if-else 判断,是字典取值的标准姿势。


2. 用 dict 合并运算符 |

最常见的写法大概是这样的:

default = {'color': 'red', 'size': 10}custom = {'size': 20, 'weight': 5}result = {**default, **custom}

老手一般这么写:

default = {'color': 'red', 'size': 10}custom = {'size': 20, 'weight': 5}result = default | custom  # Python 3.9+print(result)  # {'color': 'red', 'size': 20, 'weight': 5}

Python 3.9+ 引入字典合并运算符 |,语法更直观。

|= 可以原地更新。右侧字典的值会覆盖左侧同名键。


3. 用 collections.Counter 统计频次

很多人统计词频是这么写的:

words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']counts = {}for w in words:    counts[w] = counts.get(w, 0) + 1print(counts)

换成这样就优雅多了:

from collections import Counterwords = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']counts = Counter(words)print(counts.most_common(2))  # [('apple', 3), ('banana', 2)]

Counter 是专门用于计数的字典子类,自带 most_common、elements 等实用方法,还支持加减运算,是频次统计的利器。


4. 用 heapq 实现优先队列

看起来没问题,但其实有更好的方式:

tasks = [(3, 'low'), (1, 'high'), (2, 'mid')]tasks.sort()  # 每次插入都要重新排序 O(n log n)print(tasks[0])

其实标准库早就有答案了:

import heapqtasks = []heapq.heappush(tasks, (3, 'low'))heapq.heappush(tasks, (1, 'high'))heapq.heappush(tasks, (2, 'mid'))print(heapq.heappop(tasks))  # (1, 'high')print(heapq.nsmallest(2, tasks))  # 最小的2个

heapq 实现了最小堆,插入和弹出都是 O(log n),比每次排序 O(n log n) 高效得多,是实现优先队列的标准方案。


5. 用 bisect 维护有序列表

刚学 Python 的时候我这么写过:

sorted_list = [1, 3, 5, 7, 9]sorted_list.append(4)sorted_list.sort()  # O(n log n)

一行代码就能搞定:

import bisectsorted_list = [1, 3, 5, 7, 9]bisect.insort(sorted_list, 4)  # O(n) 插入print(sorted_list)  # [1, 3, 4, 5, 7, 9]idx = bisect.bisect_left(sorted_list, 5)  # O(log n) 查找print(idx)  # 3

bisect 模块用二分查找维护有序列表,insort 插入后自动保持有序,比 append+sort 更高效,适合需要频繁插入的有序序列场景。


速查表

场景别这样写试试这样
字典取值带默认值if/else 判断键是否存在d.get(key, default)
合并两个字典{**d1, **d2}`d1
统计词频/频次手动循环计数Counter(words).most_common(n)
优先队列列表 + sortheapq.heappush/pop
维护有序列表append + sortbisect.insort(list, val)

优雅的代码从来不是炫技,而是恰到好处。

当你不再用手动循环去凑一个计数器,当你的队列不再因为 pop(0) 而慢如蜗牛,当你的字典取值再也不用写满屏的 if key not in:

你会发现,代码变短了,思路变清晰了,连 Bug 都躲着你走了。


关于作者

写了 10 年 Python,赶上了机器学习的热潮,又撞上了大模型的浪头,每次以为学明白了,行业又变了一次。

把自己踩过的坑、走过的弯路、看过的热闹,说给还在路上的人听。

关注「鲁叶的Python」,第一时间接收技术干货。

最新文章

随机文章