获取每个项目的python dict.keys路径

时间:2012-12-20 10:39:16

标签: python parsing dictionary

我有一个看起来像这样的python dict

{'data': [{'data': [{'data': 'gen1', 'name': 'objectID'},
                   {'data': 'familyX', 'name': 'family'}],
          'name': 'An-instance-of-A'},
         {'data': [{'data': 'gen2', 'name': 'objectID'},
                   {'data': 'familyY', 'name': 'family'},
                   {'data': [{'data': [{'data': '21',
                                        'name': 'objectID'},
                                       {'data': 'name-for-21',
                                        'name': 'name'},
                                       {'data': 'no-name', 'name': None}],
                              'name': 'An-instance-of-X:'},
                             {'data': [{'data': '22',
                                        'name': 'objectID'}],
                              'name': 'An-instance-of-X:'}],
                    'name': 'List-of-2-X-elements:'}],
          'name': 'An-instance-of-A'}],
'name': 'main'}

结构重复,其规则如下:

  • dict包含'name'和'data'
  • 'data'可以包含dicts列表
  • 如果'data'不是列表,那么它就是我需要的值。
  • 'name'只是一个名字

问题在于,对于每个值,我需要知道每个父母的每个信息。

所以最后,我需要打印一个包含以下内容的列表:

objectID=gen2 family=familyY An-instance-of-X_objectID=21 An-instance-of-X_name=name-for-21

编辑:这只是我想要输出的几行中的一行。对于没有字典作为“数据”的每个项目,我需要这样一行。

因此,对于不是dict的每个数据,遍历,查找信息并打印它。

我不知道像itertools和collections这样的模块中的每个函数。但是我有什么东西可以使用吗?这叫什么(当我试图自己做研究时)?

我可以找到许多“flatten dict”方法,但不是这样,不是当我有'数据','名字'这样的时候..

1 个答案:

答案 0 :(得分:3)

这是递归有益的一个很好的例子:

input_ = {'data': [{'data': [{'data': 'gen1', 'name': 'objectID'},
                   {'data': 'familyX', 'name': 'family'}],
          'name': 'An-instance-of-A'},
         {'data': [{'data': 'gen2', 'name': 'objectID'},
                   {'data': 'familyY', 'name': 'family'},
                   {'data': [{'data': [{'data': '21',
                                        'name': 'objectID'},
                                       {'data': 'name-for-21',
                                        'name': 'name'},
                                       {'data': 'no-name', 'name': None}],
                              'name': 'An-instance-of-X:'},
                             {'data': [{'data': '22',
                                        'name': 'objectID'}],
                              'name': 'An-instance-of-X:'}],
                    'name': 'List-of-2-X-elements:'}],
          'name': 'An-instance-of-A'}],
'name': 'main'}

def parse_dict(d, predecessors, output):
    """Recurse into dict and fill list of path-value-pairs"""
    data = d["data"]
    name = d["name"]
    name = name.strip(":") if type(name) is str else name
    if type(data) is list:
        for d_ in data:
            parse_dict(d_, predecessors + [name], output)
    else:
        output.append(("_".join(map(str,predecessors+[name])), data))

result = []

parse_dict(input_, [], result)

print "\n".join(map(lambda x: "%s=%s"%(x[0],x[1]),result))

输出:

main_An-instance-of-A_objectID=gen1
main_An-instance-of-A_family=familyX
main_An-instance-of-A_objectID=gen2
main_An-instance-of-A_family=familyY
main_An-instance-of-A_List-of-2-X-elements_An-instance-of-X_objectID=21
main_An-instance-of-A_List-of-2-X-elements_An-instance-of-X_name=name-for-21
main_An-instance-of-A_List-of-2-X-elements_An-instance-of-X_None=no-name
main_An-instance-of-A_List-of-2-X-elements_An-instance-of-X_objectID=22

我希望我能正确理解你的要求。如果您不想将路径加入字符串,则可以保留前任列表。

问候,

和Thorsten