Python这语言,上手是很容易,但是精通难。用久了你就会发现,好代码和能跑的代码之间,差别还是很大的。
1. 列表推导,但别过头
列表推导简洁,但得知道分寸:
# 刚好squares = [x**2 for x in range(10) if x % 2 == 0]# 过了就难读matrix = [[x*y for y in range(5) if y != 0] for x in range(5) if x > 1]
两层嵌套是极限,再多就该拆开了。
2. 用enumerate拿索引
别再range(len(list))了:
# 旧的for i in range(len(items)): print(i, items[i])# 新的for i, item in enumerate(items, start=1): # 还能指定起始值 print(i, item)
3. 字典的setdefault
处理可能不存在的键:
data = {}key = 'user'# 啰嗦版if key not in data: data[key] = []data[key].append('value')# 干净版data.setdefault(key, []).append('value')
4. 用zip配对数据
同时遍历多个列表:
names = ['张三', '李四', '王五']scores = [85, 92, 78]# 传统做法for i in range(len(names)): print(names[i], scores[i])# 优雅做法for name, score in zip(names, scores): print(name, score)
甚至能转成字典:
dict(zip(names, scores)) # {'张三': 85, '李四': 92, '王五': 78}
5. 解包操作符*
收集和展开数据:
# 函数传参def show(name, score, city): print(f"{name}在{city}考了{score}分")data = ['张三', 85, '北京']show(*data) # 自动解包# 合并列表a = [1, 2, 3]b = [*a, 4, 5] # [1, 2, 3, 4, 5]
6. 海象运算符 :=
Python 3.8+ 的好东西:
# 避免重复计算while (line := input()) != 'quit': process(line)# 列表推导里也能用results = [y for x in data if (y := process(x)) > 0]
7. 用get处理字典
取不存在的键时不报错:
config = {'theme': 'dark', 'lang': 'zh'}# 危险mode = config['mode'] # KeyError!# 安全mode = config.get('mode', 'light') # 默认为'light'
8. 上下文管理器
不只是文件操作:
from contextlib import contextmanager@contextmanagerdef timer(name): start = time.time() try: yield finally: print(f"{name}耗时: {time.time() - start:.2f}秒")# 使用with timer('数据加载'): load_data()
9. 生成器省内存
处理大数据时:
# 列表占内存def read_lines(file): return [line.strip() for line in file]# 生成器省内存def read_lines_gen(file): for line in file: yield line.strip()# 用起来一样for line in read_lines_gen(open('data.txt')): process(line)
10. 善用collections模块
标准库里的宝贝:
from collections import defaultdict, Counter# 自动初始化字典dd = defaultdict(list)dd['key'].append(1) # 不用先检查key是否存在# 数东西words = ['apple', 'banana', 'apple', 'orange']count = Counter(words) # {'apple': 2, 'banana': 1, 'orange': 1}
技巧是工具,不是目的。代码先是给人读的,其次才是给机器执行的。用最简单的写法解决问题,就是最好的技巧。