减少不必要的循环操作
写脚本时,很多人习惯把数据处理放在循环里,尤其是嵌套循环。比如遍历一个大列表时,在每一层都做字符串拼接或文件读写,速度立马变慢。其实可以把重复操作提到循环外,或者用生成器减少内存占用。
# 慢:每次循环都打开文件
for line in lines:
with open('log.txt', 'a') as f:
f.write(line)
# 快:一次性写入
with open('log.txt', 'a') as f:
f.writelines(lines)善用内置函数和模块
Python 的 map()、filter()、join() 这些内置方法是用 C 实现的,比自己写 for 循环快不少。比如拼接大量字符串,用 ''.join(list) 就比 += 累加高效得多。
用好 subprocess 批量处理命令
在系统工具脚本中,经常要调外部命令。如果一个个跑 os.system(),每个都要启动新进程,开销很大。换成 subprocess.run() 配合管道批量执行,效率明显提升。
import subprocess
# 批量查多个文件大小
files = ['file1.txt', 'file2.txt']
result = subprocess.run(['wc', '-l'] + files, capture_output=True, text=True)
print(result.stdout)避免频繁的磁盘读写
脚本里频繁读写小文件特别拖慢速度。可以先把数据缓存到内存,处理完再统一写入。比如日志收集脚本,不要每来一条就写一次,攒够 100 条再刷盘,性能能差好几倍。
使用并发简化耗时任务
如果是处理网络请求或等待 I/O 的脚本,用 concurrent.futures 开几个线程就能大幅缩短总时间。比如批量下载图片,串行可能要几分钟,加个线程池,几十秒搞定。
from concurrent.futures import ThreadPoolExecutor
def download(url):
# 模拟下载
print(f'Downloading {url}')
urls = ['img1.jpg', 'img2.jpg', 'img3.jpg']
with ThreadPoolExecutor(max_workers=5) as executor:
executor.map(download, urls)提前优化数据结构选择
别小看 list 和 set 的区别。在判断元素是否存在的场景下,用 set 能让查找从 O(n) 降到 O(1)。比如你要比对两个大列表的交集,转成 set 再算,速度快很多。