使用fitz提取PDF文本后,如何优雅遍历列表并避免索引错误?
优化fitz提取PDF特定数值的Pythonic写法
用PyMuPDF(fitz)提取PDF文本后,会得到由元组组成的单词列表,每个元组格式为(x0, y0, x1, y1, "文本内容", block_no, block_type)。要提取"sample population"和"target population"对应的数值,原代码因遍历范围不当触发IndexError,可以用以下几种更简洁、符合Python风格的写法解决:
方案1:控制遍历索引范围
直接限制循环的索引边界,避免越界,同时替换位运算为逻辑运算:
sample_pop = 0 target_pop = 0 # 只遍历到倒数第三个元素,确保i+2不会超出列表长度 for i in range(len(wlist) - 2): current_word = wlist[i][4] next_word = wlist[i+1][4] if current_word == "sample" and next_word == "population": sample_pop = wlist[i+2][4] elif current_word == "target" and next_word == "population": target_pop = wlist[i+2][4]
方案2:滑动窗口式迭代(最Pythonic)
利用zip将连续三个元素打包,自动处理边界,无需手动计算索引:
sample_pop = 0 target_pop = 0 # 打包连续三组元素,自动停止在最后有效三元组 for prev_item, curr_item, num_item in zip(wlist, wlist[1:], wlist[2:]): prev_word = prev_item[4] curr_word = curr_item[4] if prev_word == "sample" and curr_word == "population": sample_pop = num_item[4] elif prev_word == "target" and curr_word == "population": target_pop = num_item[4]
方案3:字典映射减少重复代码
如果后续可能扩展更多类似关键词,用字典存储目标值,提升代码扩展性:
# 初始化需要提取的目标键值对 populations = {"sample": 0, "target": 0} for prev_item, curr_item, num_item in zip(wlist, wlist[1:], wlist[2:]): key = prev_item[4] # 检查当前关键词是否在目标集合中,且下一个词是population if key in populations and curr_item[4] == "population": populations[key] = num_item[4] # 提取结果 sample_pop = populations["sample"] target_pop = populations["target"]
原代码的核心问题
- 遍历范围未做限制:循环到列表最后两个元素时,
i+1或i+2会超出列表索引,触发IndexError; - 错误使用位运算符
&:逻辑判断应使用and,&是位运算,仅在布尔值场景下巧合生效,不符合Python逻辑判断的规范。
内容的提问来源于stack exchange,提问作者magladde
相关产品推荐
相关产品推荐

