使用python通过Yaml解析

阿什维尼·库玛(Ashwini kumar)

我正在尝试通过阅读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')
安通

我不会打扰发生器,如果您愿意的话,您将需要产生一些特殊的令牌,这表明以下令牌构成了一个新的“配置”。

我建议您将一个空列表作为第二个参数传递给递归调用的函数,并在找到配置时追加到该列表。只要确保在递归时也通过列表即可:

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'))

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章