You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用原生Python将3DS格式节点列表解析为嵌套Dict

用原生Python解析3DS自定义节点为嵌套字典

当然可以用原生Python实现这个解析需求!你的核心问题在于如何递归地识别键值对——尤其是处理那些多值属性和嵌套的子节点结构。我来帮你梳理思路并完善代码:

核心解析思路

我们需要一个递归函数来遍历输入的列表:

  1. 遍历过程中,遇到以*开头的字符串时,将其作为字典的键
  2. 从当前位置开始,收集后续的元素作为值,直到遇到下一个以*开头的键或者列表结束
  3. 如果收集到的元素是子列表,递归调用解析函数将其转为子字典
  4. 如果值的长度大于1,保留为列表;长度为1则直接取单个值;同时注意把字符串类型的数字转为数值类型(整数/浮点数)

完整实现代码

def parse_3ds_node(node_list):
    result = {}
    i = 0
    length = len(node_list)
    
    while i < length:
        # 识别键:以*开头的字符串
        if isinstance(node_list[i], str) and node_list[i].startswith('*'):
            key = node_list[i].strip('*')  # 去掉开头的*作为键名
            i += 1
            values = []
            
            # 收集值,直到遇到下一个键或者列表结束
            while i < length and not (isinstance(node_list[i], str) and node_list[i].startswith('*')):
                item = node_list[i]
                # 如果是嵌套列表,递归解析为子字典
                if isinstance(item, list):
                    values.append(parse_3ds_node(item))
                else:
                    # 尝试转换为数值类型
                    try:
                        # 先试整数,不行试浮点数
                        num_val = int(item)
                    except ValueError:
                        try:
                            num_val = float(item)
                        except ValueError:
                            # 保留原始字符串(比如带引号的名称)
                            num_val = item.strip('"')  # 去掉引号
                    values.append(num_val)
                i += 1
            
            # 处理值:单值直接赋值,多值保留列表
            if len(values) == 1:
                result[key] = values[0]
            else:
                result[key] = values
        else:
            # 跳过非键的顶层元素(理论上输入结构不会有这种情况)
            i += 1
    return result

# 测试你提供的示例节点列表
sample_node = [['*NODE_NAME', '"30deg017"', '*CAMERA_TYPE', 'Target', '*NODE_TM', ['*NODE_NAME', '"30deg017"', '*INHERIT_POS', '0', '0', '0', '*INHERIT_ROT', '0', '0', '0', '*INHERIT_SCL', '1', '1', '1', '*TM_ROW0', '0.0939', '-0.9815', '-0.1668', '*TM_ROW1', '0.8819', '0.0043', '0.4714', '*TM_ROW2', '-0.4619', '-0.1913', '0.8660', '*TM_ROW3', '-230.9698', '-95.6709', '433.0127', '*TM_POS', '-230.9698', '-95.6709', '433.0127', '*TM_ROTAXIS', '-0.3314', '0.1476', '0.9319', '*TM_ROTANGLE', '1.5887', '*TM_SCALE', '1.0000', '1.0000', '1.0000', '*TM_SCALEAXIS', '0.9925', '-0.1222', '-0.0000', '*TM_SCALEAXISANG', '0.1253'], '*NODE_TM', ['*NODE_NAME', '"30deg017.Target"', '*INHERIT_POS', '0', '0', '0', '*INHERIT_ROT', '0', '0', '0', '*INHERIT_SCL', '0', '0', '0', '*TM_ROW0', '1.0000', '0.0000', '0.0000', '*TM_ROW1', '0.0000', '1.0000', '0.0000', '*TM_ROW2', '0.0000', '0.0000', '1.0000', '*TM_ROW3', '0.0000', '0.0000', '0.0000', '*TM_POS', '0.0000', '0.0000', '0.0000', '*TM_ROTAXIS', '0.0000', '0.0000', '0.0000', '*TM_ROTANGLE', '0.0000', '*TM_SCALE', '1.0000', '1.0000', '1.0000', '*TM_SCALEAXIS', '0.0000', '0.0000', '0.0000', '*TM_SCALEAXISANG', '0.0000'], '*CAMERA_SETTINGS', ['*TIMEVALUE', '0', '*CAMERA_NEAR', '0.0000', '*CAMERA_FAR', '1000000.0000', '*CAMERA_FOV', '1.1752', '*CAMERA_TDIST', '500.0000']]]

# 注意示例是嵌套在一个列表里,所以取第一个元素解析
parsed_result = parse_3ds_node(sample_node[0])
import pprint
pprint.pprint(parsed_result)

代码说明

  1. 递归处理嵌套结构:遇到子列表时,调用parse_3ds_node递归解析,自动生成嵌套字典
  2. 数值类型转换:自动将字符串形式的整数、浮点数转为对应数值,同时保留带引号的节点名称(去掉引号)
  3. 键值配对逻辑:通过循环遍历,精准识别每个键对应的所有值,自动处理单值/多值场景
  4. 原生Python实现:完全不需要第三方库,依赖Python内置的类型判断和循环逻辑

测试输出示例

解析后的字典会像这样(部分展示):

{'CAMERA_SETTINGS': {'CAMERA_FAR': 1000000.0,
                     'CAMERA_FOV': 1.1752,
                     'CAMERA_NEAR': 0.0,
                     'CAMERA_TDIST': 500.0,
                     'TIMEVALUE': 0},
 'CAMERA_TYPE': 'Target',
 'NODE_NAME': '30deg017',
 'NODE_TM': [{'INHERIT_POS': [0, 0, 0],
              'INHERIT_ROT': [0, 0, 0],
              'INHERIT_SCL': [1, 1, 1],
              'NODE_NAME': '30deg017',
              'TM_POS': [-230.9698, -95.6709, 433.0127],
              ...},
             {'INHERIT_POS': [0, 0, 0],
              'INHERIT_ROT': [0, 0, 0],
              'INHERIT_SCL': [0, 0, 0],
              'NODE_NAME': '30deg017.Target',
              ...}]}

你可以把这个解析函数集成到你现有的AllCameras类里,替换掉原来的parse_node方法,就能完成完整的解析流程了。

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:58:11