【问题标题】:Iterate over nested yaml dictionary from python从python迭代嵌套的yaml字典
【发布时间】:2019-08-05 16:18:06
【问题描述】:

通过解析类似于以下格式的 yaml 文档,我已经安全加载了 python 对象,

envdata = yaml.safe_load(数据)

id: XXX
name: XXX
tecVersion: 1

wrapper: #category
    wrapper-box-1: #instance
        host: XXX
        port: 4567
        tags:
          - ABC
          - VTR


powerWrapper: #category
     pw-box-45: #instance
         host: YYY
         port: 7890
         tags:
           - ABC

每个类别都是顶级数组对象,实例是类别内的数组对象。

要求是,给定标签 ex:ABC,我想将每个类别中的所有匹配实例作为一个列表。如何迭代每个元素并比较标签并以最佳方式将所有匹配的实例添加到实例数组中?

【问题讨论】:

  • 那是无效的 YAML,你从根级别的映射开始,然后切换到序列元素。更正您的 YAML 输入并为我们提供比加载 YAML 更多的(失败的)程序。
  • @Anthon 现在有效。实际上我已经提到了我的要求,我需要解决方案算法。我也更新了问题。
  • 因为您没有包含失败的程序,也没有以明确的方式包含预期的输出,所以这仍然非常模糊。你想要匹配的 ABC 实例作为一个列表:所以你想要 ["ABC", "ABC"]?

标签: python python-3.x dictionary iterator yaml


【解决方案1】:

(1.) 每个类别都是一个顶级数组对象,实例是类别内的一个数组对象。

(2.) 我怎样才能...比较标签并将所有匹配的实例添加到实例数组中...?

(1.) 中的定义并不完美,但足以使用。 我不同意您使用“数组”或list 这个词,因为该类别包含的显然是“地图”或dict。 我觉得,如果每个实例都保证包含一个名为'instance''id' 或其他名称的键,以将它们与'tecVersion' 等兄弟条目区分开来,那会更好一些。 或者,所有实例都可以在具有创意名称的键下向下推一级,例如,让我们看看,也许我们称之为'instances'

您明确表示'wrapper' 是一个“类别”。 我不知道'wrapper-box-1' 可能被称为什么。 您没有在示例数据中包含'wrapper-box-2',这太糟糕了。

这是yaml 返回的内容:

>>> pprint.pprint(envdata)
{'id': 'XXX',
 'name': 'XXX',
 'powerWrapper': {'pw-box-45': {'host': 'YYY', 'port': 7890, 'tags': ['ABC']}},
 'tecVersion': 1,
 'wrapper': {'wrapper-box-1': {'host': 'XXX',
                               'port': 4567,
                               'tags': ['ABC', 'VTR']}}}

好的,让我们迭代:

def get_tags(putative_category):
    """Generator, returns tags if the input appears to be a category."""
    try:
        for undefined_box_concept, attributes in putative_category.items():
            tags = attributes['tags']
            yield tags
    except (AttributeError, KeyError):
        pass

for category_name, category in envdata.items():
    for tags in get_tags(category):
        print(tags, category_name, category)

输出:

['ABC', 'VTR'] wrapper {'wrapper-box-1': {'host': 'XXX', 'port': 4567, 'tags': ['ABC', 'VTR']}}
['ABC'] powerWrapper {'pw-box-45': {'host': 'YYY', 'port': 7890, 'tags': ['ABC']}}

您的问题陈述有点含糊。 一旦你拿到了标签,我就不清楚你想用它们做什么。 对于 (2.),使用我提供的生成器,带有嵌套 for 循环的列表理解就足够了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 2021-11-29
    • 1970-01-01
    相关资源
    最近更新 更多