PDF提取:如何修改列表中namedtuple的单个元素并合并项目符号内容?
PDF提取[V2G]条目及项目符号的处理方案
问题背景
我编写了从PDF提取信息的Python脚本,将每页读取为文本块。需求是:当检测到[V2G]标识时,保存标题、副标题、[V2G]相关文本及后续项目符号列表。
现有代码:
data = [] req = namedtuple('Req', 'a b c d e f') for page in doc: dic = page.get_text("dict") blocks = dic['blocks'] # text blocks ... for b in blocks : # 标题处理 if (font1 == 'Cambria-Bold'): nr = text.partition(" ")[0] title = text.partition(" ")[2] # 副标题处理 elif font1 == 'Cambria': Sub_nr = text.partition(" ")[0] sub_title = text.partition(" ")[2] # [V2G]文本处理 elif text.startswith('[V2G'): id = text.replace('[', '') txt = text1.strip() data.append(req(nr, title, Sub_nr, sub_title, id, txt)) # 项目符号列表处理(当前有问题) elif text.startswith("—"): text += "\n" + text
当前问题:项目符号列表位于[V2G]文本的下一个块,且并非所有[V2G]条目都带有项目符号列表。需要将项目符号文本与txt变量内容合并后存入namedtuple的f参数,更新列表最后一行的对应元素,想问是否可仅修改namedtuple的单个属性并更新列表中的对应元素?
解决方案
核心结论
namedtuple是不可变数据类型,无法直接修改单个属性,但可以通过以下两种方式实现需求:
方法1:使用namedtuple的_replace()方法生成新实例
_replace()会创建一个新的namedtuple实例,替换指定字段的值,之后用新实例覆盖列表中的旧元素:
# 捕获项目符号块时修改代码 elif text.startswith("—"): if data: # 确保已有对应的[V2G]条目 last_req = data[-1] # 合并原有文本与当前项目符号内容 updated_content = last_req.f + "\n" + text.strip() # 生成新实例并替换列表最后一项 data[-1] = last_req._replace(f=updated_content)
方法2:改用可变数据结构
如果觉得namedtuple的不可变性过于繁琐,可以替换成普通字典或者dataclass:
- 用dataclass的示例:
from dataclasses import dataclass @dataclass class Req: a: str b: str c: str d: str e: str f: str # 后续代码中直接修改属性即可 elif text.startswith("—"): if data: data[-1].f += "\n" + text.strip()
额外注意事项
- 处理时要判断
data列表不为空,避免出现索引越界错误 - 如果PDF中存在项目符号块不对应任何[V2G]条目的情况,需要添加过滤逻辑,避免无效更新
- 可以在初始化[V2G]条目时,将
f字段初始化为空字符串或初始文本,后续逐步追加项目符号内容
内容的提问来源于stack exchange,提问作者user34088
相关产品推荐
相关产品推荐

