如何在Pyparsing中扁平化字典,生成顶层解析结果条目
解决Pyparsing解析结果层级嵌套问题
你遇到的这个嵌套层级问题其实很好解决,核心是利用Pyparsing的ParseResults对象替代普通字典作为parse action的返回值,这样就能直接把生成的comments和urls放到解析结果的顶层,同时覆盖掉原始令牌。
方法一:返回ParseResults对象替代字典
Pyparsing在处理parse action的返回值时,如果是ParseResults类型,会自动把它的键值对合并到上层的结果集中,而不是作为嵌套的子字典。修改你的代码如下:
from pyparsing import ParseResults # 别忘了导入这个类 def process_comments(_1,_2,token): urls = [] comments = [] # ... 这里写你的转换逻辑 ... # 用ParseResults替代普通字典返回 return ParseResults({"comments": comments, "urls": urls}) # 注意这里不需要再调用setResultsName("comments")了 comments = ZeroOrMore(Suppress(Keyword("comment")) + quotes.copy()).setParseAction(process_comments)
这样解析完成后,你直接就能从顶层结果中拿到results.comments和results.urls,完全没有嵌套层级。
方法二:直接修改传入的token参数
如果你不想额外导入ParseResults,也可以在parse action里直接修改传入的token对象:清空原始令牌,再把你的新键值对加进去。因为parse action如果返回None,Pyparsing会使用修改后的token作为最终结果:
def process_comments(_1,_2,token): urls = [] comments = [] # ... 转换逻辑 ... # 清空原始令牌内容 token.clear() # 添加新的键值对到token中 token["comments"] = comments token["urls"] = urls # 不需要返回任何内容(或者返回None) comments = ZeroOrMore(Suppress(Keyword("comment")) + quotes.copy()).setParseAction(process_comments)
为什么原来的方法会产生嵌套?
你之前返回普通字典时,setResultsName("comments")会把这个字典作为comments键的值,自然就形成了results.comments["list"]和results.comments["urls"]的嵌套结构。而返回ParseResults或者直接修改token,都是直接操作顶层的结果集合,所以不会有多余的层级。
至于你提到的「自定义setParseAction的Empty令牌」,其实完全不需要这个功能——上面的两种方法已经能完美实现你想要的效果,而且更简洁直接。
内容的提问来源于stack exchange,提问作者i30817
相关产品推荐
相关产品推荐

