【问题标题】:Getting a python dict.keys trail for each item为每个项目获取 python dict.keys 跟踪
【发布时间】:2012-12-20 10:39:16
【问题描述】:

我有一个看起来像这样的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'}

结构是重复的,它的规则是这样的:

  • 字典包含“名称”和“数据”
  • 'data' 可以包含字典列表
  • 如果“数据”不是一个列表,它就是我需要的值。
  • 'name' 只是一个名字

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

所以最后,我需要打印一个包含如下项目的列表:

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

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

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

我不知道模块中的每个函数,比如 itertools 和集合。但是里面有什么我可以使用的吗?这叫什么(当我尝试自己进行研究时)?

我可以找到很多“flatten dict”方法,但不是这样的,当我有'data','name'时不是这样的......

【问题讨论】:

  • 我认为这是一个疯狂的字典?为什么你有这样的字典,它不是你能得到更好的吗?
  • 这看起来很像json 数据。就是这样吗?如果是这样,你可以直接使用json模块
  • 请给出这个应该如何工作的基本概念。样本输入,样本输出。以及您尝试过的功能。
  • 看看这个字典,我要做的第一件事就是在每个级别上转换每个字典,从拥有'data' 键和@987654325 @key 使'name' 值成为指向'data' 值的键。这将减少查看、思考和使用的痛苦。
  • 我试图解析的数据以类似 yaml 的语法组织(但根本不是 yaml)。我将这个字典放在一个怪物列表中,因为列表中的一些名字会重复它们自己。因此,不是一堆键发生冲突,而是我必须存储它的方式。我从中获取此信息的来源是第 3 方信息脚本,它为我提供了一些数据结构的概述。

标签: python parsing dictionary


【解决方案1】:

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

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

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

您好,

索斯滕

【讨论】:

  • OP 的示例去掉了名称中的尾随冒号 - 您可能想要添加该行为。除此之外,我在这里找不到任何问题,尽管我仍然不知道为什么 OP 要以这种方式打印数据,特别是考虑到它很难区分 X 中的不同实例相同的列表分开。
  • 我不会自己读这个。我的日志分析器会这样做 :) 所以这是它的完美格式..
  • 这个解决方案几乎就是我想要的,谢谢!我会稍微完善一下以满足确切的需求。
  • 很高兴这有帮助。马克,我包含了你的建议,谢谢。
  • if type(data) is list:?我认为现在首选的形式是if isinstance(data, list):。见stackoverflow.com/questions/1549801/…
猜你喜欢
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多