【问题标题】:Parsing through a yaml using python使用python解析yaml
【发布时间】:2019-06-27 01:21:41
【问题描述】:

我正在尝试通过读取 yaml 来制作包含 2 个键的元组。

结构看起来像

abc:
 xyz:
  efg:
   fgh:
     a: b
  rty:
   ccc:
    - a_table: t0
      b_table: t1

zzz:
 xyz:
  efg:
   fgh:
     a: b
  rty:
   ccc:
    - a_table: t2
      b_table: t3
eee:
 xyz:
  efg:
   fgh:
     a: b
  rty:
   ccc:
    - a_table: t5
      b_table: t6
fff:
 xyz:
  efg:
   fgh:
     a: b
  rty:
   ccc:
    - a_table: t9
      b_table: t10

yaml 中有多个条目,结构始终保持不变。我希望将 t0 和 t1 分组,以便我知道它们是 yaml 中一个配置的一部分。有时我可能只得到a_table,有时两者兼而有之。

我已经尝试过的: 我尝试创建一个生成器来分别获取 a_table 和 b_table 的列表,但我无法映射它们,因为它们的长度不同。

def list_convert(document):

   return list(key_find(document))


def key_find(document):

  if isinstance(document, dict):
    for k, v in iteritems(document):
        if k == 'a_table':
             yield v
        elif k == 'b_table':
            yield v

        if isinstance(v, dict):
            for result in key_find(v):
                yield result
        elif isinstance(v, list):
            for d in v:
                for result in key_find(d):
                    yield result

我怎样才能做到这一点?

所以我添加了 4 个配置,它们都出现了 a_table 和 b_table。

我得到的当前输出是

Present O/P -('t0', 't1', 't2', 't3', 't5', 't6', 't9', 't10')
Expected O/P - ('t0', 't1'),('t2', 't3'),('t5', 't6'),('t9', 't10')

【问题讨论】:

  • 根据建议更新了问题的详细信息
  • 更新了答案。顺便说一句,在您的示例中,我希望配置具有不同数量的 X_table
  • 天才!非常感谢你这么快的回复。这就是我所缺少的,无法弥补逻辑。

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


【解决方案1】:

我不会打扰生成器,如果你这样做,你需要产生一些特殊的令牌, 这表明以下令牌构成了一个新的“配置”。

我建议你传入一个空列表作为第二个 递归调用函数的参数并在找到时附加到该列表 一个配置。只需确保在递归时也通过列表:

import sys
import ruamel.yaml

yaml_str = """\
abc:
 xyz:
  efg:
   fgh:
     a: b
  rty:
   ccc:
    - a_table: t0
      b_table: t1

zzz:
 xyz:
  efg:
   fgh:
     a: b
  rty:
   ccc:
    - b_table: t3
eee:
 xyz:
  efg:
   fgh:
     a: b
  rty:
   ccc:
    - a_table: t5
fff:
 xyz:
  efg:
   fgh:
     a: b
  rty:
   ccc:
    - a_table: t9
      b_table: t10
"""


def build_list(d, res):
    if isinstance(d, dict):
        config = []
        for k in d:
            if k == 'a_table':
                config.append(d[k])
            elif k == 'b_table':
               config.append(d[k])
            else:
                build_list(d[k], res)
        if config:   # only filled if a ?_table key was found
            res.append(tuple(config))
    elif isinstance(d, list):
        for item in d:
            build_list(item, res)



def get_table_entries_as_tuple(d):
    res = []
    build_list(d, res)
    return tuple(res)


yaml = ruamel.yaml.YAML()

res = get_table_entries_as_tuple(yaml.load(yaml_str))
print(type(res), res)

给出:

<class 'tuple'> (('t0', 't1'), ('t3',), ('t5',), ('t9', 't10'))

请注意,我略微更改了您的输入,以确保部分配置也能正常工作。

【讨论】:

    猜你喜欢
    • 2015-12-06
    • 1970-01-01
    • 2012-01-11
    • 2013-01-25
    • 2020-10-14
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    相关资源
    最近更新 更多