Python递归地维护键控深度 投入/目标

Python递归地维护键控深度 投入/目标,python,recursion,Python,Recursion,我的输入数据是一个OrderedPict,它可以有不同深度的嵌套OrderedPict,因此我选择递归地处理对该输出的解析。所需的输出是带有标题的csv 问题的阐述 一旦我能够在完成分支的所有叶子后遍历备份分支时正确定义字段\ u name,我下面的代码就会起作用。(即,Type_1.Field_3.Data将被错误地称为Type_1.Field_2.Field_3.Data) 分支上的叶子用完后,我想从字段名称中删除最后一个.Field\u x,以便为以下对象添加新的(正确的)叶子 求助 有人

我的输入数据是一个OrderedPict,它可以有不同深度的嵌套OrderedPict,因此我选择递归地处理对该输出的解析。所需的输出是带有标题的csv

问题的阐述 一旦我能够在完成分支的所有叶子后遍历备份分支时正确定义
字段\ u name
,我下面的代码就会起作用。(即,
Type_1.Field_3.Data
将被错误地称为
Type_1.Field_2.Field_3.Data

分支上的叶子用完后,我想从
字段名称
中删除最后一个
.Field\u x
,以便为以下对象添加新的(正确的)叶子

求助 有人看到我在哪里可以包含此功能吗?谢谢

依赖项:
代码段: Salesforce输出示例:
{
“记录”:[
{
“属性”:{
“类型”:“Obj_1”,
“url”:”
},
“类型1”:{
“属性”:{
“类型”:“类型1”,
“url”:”
},
“字段_1”:“,
“字段2”:{
“属性”:{
“类型”:“字段2”,
“url”:”
},
“数据”:”
},
“字段_3”:“,
“字段_4”:“,
“字段_5”:{
“属性”:{
“类型”:“字段2”,
“url”:”
},
“数据_1”:{
“属性”:{
“类型”:“数据类型1”,
“url”:”
},
“数据”:”
}
},
“字段_6”:1.0
},
“类型2”:{
“属性”:{
“类型”:“类型2”,
“url”:”
},
“字段_1”:“,
“字段_2”:”
}
}
]
}

我想出了一个快速解决方案。我将只记下我的想法,并将我编写的代码附加到最后

本质上,您的问题是您一直试图在适当的位置修改
路径
,这是行不通的。而是做一些类似的事情

new_path = path + '.{obj}'.format(obj=f)
_traverse_output(f, v, fields, row, new_path)
关于这一点的注意事项:它不一定会产生一行,其中的值与标题的顺序相同(即,如果类型_1.Field_1位于标题列表的位置0,则与之对应的值可能不相同)

解决这个问题(通常处理CSV)的简单方法是从使用DictWriter,然后将空字典传递给第一次调用,其中键将是字段名,值将是它们的值

解决此问题的另一种方法是使用无字符串或空字符串预先填充行列表,然后使用
list.index
方法将值分配到适当的位置

我编写了一个
\u traverse\u output
的实现,作为每个示例,尽管它们与您的代码略有不同。它们接受
记录列表中的一个元素

字典示例

def _traverse_output_with_dict(record, fields, row_values, field_name=''):
    for obj, value in record.iteritems():
        new_field_name = '{}.{}'.format(field_name, obj) if field_name else obj
        print new_field_name
        if not isinstance(value, dict):
            if new_field_name in fields:
                row_values[new_field_name] = value
        else:
            _traverse_output_with_dict(value, fields, row_values, new_field_name)
def _traverse_output_with_list(record, fields, row, field_name=''):
    while len(row) < len(fields):
        row.append('')

    for obj, value in record.iteritems():
        new_field_name = '{}.{}'.format(field_name, obj) if field_name else obj
        print new_field_name
        if not isinstance(value, dict):
            if new_field_name in fields:
                row[fields.index(new_field_name)] = value
        else:
            _traverse_output_with_list(value, fields, row, new_field_name)
列出示例

def _traverse_output_with_dict(record, fields, row_values, field_name=''):
    for obj, value in record.iteritems():
        new_field_name = '{}.{}'.format(field_name, obj) if field_name else obj
        print new_field_name
        if not isinstance(value, dict):
            if new_field_name in fields:
                row_values[new_field_name] = value
        else:
            _traverse_output_with_dict(value, fields, row_values, new_field_name)
def _traverse_output_with_list(record, fields, row, field_name=''):
    while len(row) < len(fields):
        row.append('')

    for obj, value in record.iteritems():
        new_field_name = '{}.{}'.format(field_name, obj) if field_name else obj
        print new_field_name
        if not isinstance(value, dict):
            if new_field_name in fields:
                row[fields.index(new_field_name)] = value
        else:
            _traverse_output_with_list(value, fields, row, new_field_name)
def _遍历_输出_和_列表(记录、字段、行、字段_名称=“”):
而len(行)
不是答案,但您可以简化为
不是实例(v,(list,dict,tuple))
@PadraicCunningham注意到并更新了!谢谢你的接球!我找不到您处理“字段名称”和我的代码之间的区别。我不明白如果字段\名称else obj
会如何影响这一点。关于输出顺序,由于我正在使用有序的字典输入,解析它,并输出列表列表,我不必担心通过列表索引或字典额外确保正确的顺序。通过使用您的答案并将部分内容调整到我的代码,我有一个有效的解决办法。非常感谢。
def _traverse_output_with_list(record, fields, row, field_name=''):
    while len(row) < len(fields):
        row.append('')

    for obj, value in record.iteritems():
        new_field_name = '{}.{}'.format(field_name, obj) if field_name else obj
        print new_field_name
        if not isinstance(value, dict):
            if new_field_name in fields:
                row[fields.index(new_field_name)] = value
        else:
            _traverse_output_with_list(value, fields, row, new_field_name)