如何基于复杂嵌套列表构建嵌套pyparsing.Dict结构?
用pyparsing将嵌套括号表达式转换成嵌套Dict
嘿,这个需求我之前刚好折腾过,pyparsing.nestedExpr()确实是处理这类嵌套结构的利器,它能帮我们把带括号的嵌套文本解析成嵌套列表,接下来只需要写个递归函数把列表转成字典就行,给你一步步捋清楚怎么做~
第一步:定义解析器,把文本转成嵌套列表
首先得告诉pyparsing怎么识别输入里的元素——比如标识符(像unitsOfMeasure这种不带引号的名称)、带引号的字符串、数字。然后用nestedExpr处理括号的嵌套结构:
import pyparsing as pp # 定义基础元素解析规则 # 标识符:以字母开头,后面可跟字母、数字、下划线 identifier = pp.Word(pp.alphas, pp.alphanums + "_") # 字符串:带双引号,解析后自动去掉引号 string_literal = pp.quotedString.addParseAction(pp.removeQuotes) # 数字:自动识别整数、浮点数 number = pp.pyparsing_common.number # 嵌套表达式的内容可以是标识符、字符串、数字,或者另一个嵌套表达式 expr_content = identifier | string_literal | number # 创建嵌套表达式解析器,用()作为分隔符 nested_parser = pp.nestedExpr(opener='(', closer=')', content=expr_content)
然后用这个解析器处理你的输入文本:
input_works = ''' (unitsOfMeasure (altitudeUnits "m") (capacitanceUnits "pF") (designUnits "MIL") (drawingUnits "MIL") (drawingAccuracy 2) (drawingHeight 28000) )''' # 解析输入,得到嵌套列表(取第一个元素是因为parseString会返回包含顶层列表的结果) parsed_list = nested_parser.parseString(input_works).asList()[0]
这时候parsed_list会是这样的嵌套列表:
['unitsOfMeasure', ['altitudeUnits', 'm'], ['capacitanceUnits', 'pF'], ['designUnits', 'MIL'], ['drawingUnits', 'MIL'], ['drawingAccuracy', 2], ['drawingHeight', 28000]]
第二步:写递归函数,把嵌套列表转成字典
接下来需要一个递归函数,遍历嵌套列表,把每个以字符串开头的子列表转换成字典的键值对,遇到嵌套的子列表就递归处理:
def list_to_nested_dict(lst): # 处理以键开头、后面跟着多个键值对的结构(比如(root (key1 val1) (key2 val2))) if isinstance(lst, list) and len(lst) > 0 and isinstance(lst[0], str): key = lst[0] value = {} for item in lst[1:]: # 每个子项如果是列表,递归转换成字典后合并进来 if isinstance(item, list): sub_dict = list_to_nested_dict(item) value.update(sub_dict) # 处理特殊情况:比如(key val1 val2)这种多值的情况,把值存成列表 else: value[key] = lst[1:] return {key: value} # 处理简单的键值对结构(比如(key val)) elif isinstance(lst, list) and len(lst) == 2: key, val = lst if isinstance(val, list): return {key: list_to_nested_dict(val)} else: return {key: val} # 普通值(字符串、数字)直接返回 else: return lst
第三步:测试转换效果
现在把解析后的列表传入函数,就能得到嵌套字典了:
nested_dict = list_to_nested_dict(parsed_list) print(nested_dict)
输出结果就是你想要的嵌套结构:
{ 'unitsOfMeasure': { 'altitudeUnits': 'm', 'capacitanceUnits': 'pF', 'designUnits': 'MIL', 'drawingUnits': 'MIL', 'drawingAccuracy': 2, 'drawingHeight': 28000 } }
扩展说明
这个方案还能处理更复杂的多层嵌套场景,比如:
complex_input = ''' (settings (userInfo (name "Alice") (age 30) (address (city "NY") (zip 10001))) (display (theme "dark") (fontSize 14)) )''' parsed_complex = nested_parser.parseString(complex_input).asList()[0] complex_dict = list_to_nested_dict(parsed_complex)
转换后的字典会自动保留多层嵌套关系,完全满足复杂结构的需求。
内容的提问来源于stack exchange,提问作者code_warrior
相关产品推荐
相关产品推荐

