Python刷题神器itertools.pairwise函数实战指南附LeetCode高频题解在算法竞赛和日常编程中处理连续元素对的需求无处不在。无论是字符串中的相邻字符比较、数组中的连续子序列分析还是时间序列数据的滑动窗口计算传统写法往往需要手动控制索引既容易出错又不够优雅。Python的itertools.pairwise函数正是为解决这类问题而生——它像一把精巧的瑞士军刀能将冗长的循环代码压缩成简洁高效的表达式。让我们从一个真实场景开始假设你需要统计字符串中最长的连续字母序列如abcde传统解法需要维护双指针和多个临时变量。而使用pairwise配合map和ord函数只需3行核心代码就能解决问题。这种对比正是本文要展示的——如何用标准库工具替代手工轮子让代码既符合Pythonic风格又在LeetCode等平台获得更好的运行时表现。1. 理解pairwise的核心机制1.1 函数行为解析itertools.pairwise(iterable)生成一个迭代器产出输入可迭代对象中所有连续重叠对。例如from itertools import pairwise # 基础字符串处理 print(list(pairwise(ABCD))) # 输出[(A, B), (B, C), (C, D)] # 数值序列分析 data [10, 20, 30, 40] print([y-x for x,y in pairwise(data)]) # 计算差值[10, 10, 10]关键特性输出元素数量总是比输入少1输入需要至少2个元素否则返回空迭代器支持任何可迭代对象字符串、列表、生成器等1.2 底层实现原理通过Python标准库源码可以理解其工作方式def pairwise(iterable): iterator iter(iterable) a next(iterator, None) for b in iterator: yield a, b a b这个实现展示了几个重要技术点iter()将输入转化为迭代器对象next()预取第一个元素作为滑动窗口起点yield逐步生成相邻元素对2. LeetCode高频题型实战2.1 字符串连续序列问题例题LeetCode 2414. 最长的连续字母序列传统解法def longestContinuousSubstring(s: str) - int: max_len current 1 for i in range(1, len(s)): if ord(s[i]) - ord(s[i-1]) 1: current 1 max_len max(max_len, current) else: current 1 return max_lenpairwise优化版from itertools import pairwise def longestContinuousSubstring(s: str) - int: max_len current 1 for a, b in pairwise(map(ord, s)): current current 1 if a 1 b else 1 max_len max(max_len, current) return max_len优势对比维度传统写法pairwise版本代码行数8行5行索引操作显式使用i和i-1隐式处理可读性需要理解索引关系直接表达业务逻辑2.2 数组分组处理例题LeetCode 1502. 判断能否形成等差数列标准解法def canMakeArithmeticProgression(arr: List[int]) - bool: arr.sort() diff arr[1] - arr[0] for i in range(2, len(arr)): if arr[i] - arr[i-1] ! diff: return False return Truepairwise改进版from itertools import pairwise def canMakeArithmeticProgression(arr: List[int]) - bool: arr.sort() diffs {y-x for x,y in pairwise(arr)} return len(diffs) 1这种写法利用集合推导式直接检查所有差值是否一致避免了显式循环控制。3. 性能优化与边界处理3.1 内存效率对比当处理大型数据集时pairwise作为迭代器具有显著优势# 生成1GB大小的测试数据 large_data (x for x in range(10**8)) # 内存消耗对比 import sys print(sys.getsizeof(pairwise(large_data))) # 输出56迭代器固定开销而先将数据转换为列表再处理list_data list(large_data) # 消耗约800MB内存 print(sys.getsizeof(list_data)) # 输出接近1GB3.2 常见陷阱与解决方案问题1输入元素不足try: print(next(pairwise([1]))) # 触发StopIteration except StopIteration: print(处理空迭代情况)解决方案def safe_pairwise(items): it iter(items) try: first next(it) except StopIteration: return for second in it: yield first, second first second问题2无限迭代器处理from itertools import count # 危险操作会无限循环 # for x,y in pairwise(count()): # print(x,y) # 安全方案 limited zip(count(), islice(count(), 1, None)) for x,y in islice(limited, 10): # 只取前10对 print(x,y)4. 进阶应用模式4.1 滑动窗口统计计算移动平均值的高效实现from itertools import pairwise, tee def sliding_avg(data, window3): it1, it2 tee(data) next(it2, None) next(it2, None) for (x,_), (_,z) in zip(pairwise(it1), pairwise(it2)): yield (x z) / 2 # 示例计算5日移动平均线 stock_prices [120, 122, 121, 123, 124, 125, 126] print(list(sliding_avg(stock_prices))) # 输出[121.5, 122.0, 123.0, 124.0]4.2 与其它itertools工具组合链式处理示例from itertools import chain, pairwise # 合并多个数据源后处理 sources [ [10, 20, 30], [40, 50], [60, 70, 80, 90] ] merged chain.from_iterable(sources) deltas [y-x for x,y in pairwise(merged)] print(deltas) # 输出[10, 10, 10, 10, 10, 10, 10]分组处理技巧from itertools import groupby, pairwise data [1, 3, 5, 2, 4, 6, 8, 7] # 找出所有递增序列 for k, g in groupby(pairwise(data), keylambda x: x[1] x[0]): if k: print(list(g)) # 输出相邻递增对在实际项目中pairwise经常与这些工具配合使用zip并行处理多个序列filterfalse筛选不符合条件的元素对accumulate计算累积结果