【问题标题】:Append duplicate key value pair to nested dictionary in YAML将重复的键值对附加到 YAML 中的嵌套字典
【发布时间】:2019-02-11 04:47:23
【问题描述】:

我正在尝试通过 python 脚本将重复键:值对附加到 YAML 文件中的嵌套字典中。以下是我为实现此目的而编写的代码的 sn-p:

import click
import ruamel.yaml

def organization():
    org_num = int(input("Please enter the number of organizations to be created: "))
    org_val = 0
    while org_val!= org_num:
        print ("")
        print("Please enter values to create Organizations")
        print ("")
        for org in range(org_num):
            organization.org_name = str(raw_input("Enter the Organization Name: "))
            organization.org_description = str(raw_input("Enter the Description of Organization: "))
            print ("")
            if click.confirm("Organization Name: "+ organization.org_name + "\nDescription: "+ organization.org_description + "\nIs this Correct?", default=True):
                if org_val == 0:
                    org_val = org_val + 1
                    yaml = ruamel.yaml.YAML()
                    org_data = dict(
                        organizations=dict(
                            name=organization.org_name,
                            description=organization.org_description,
                        )
                    )
                    with open('input.yml', 'a') as outfile:
                        yaml.indent(mapping=2, sequence=4, offset=2)
                        yaml.dump(org_data, outfile)

               else:
                   org_val = org_val + 1
                   yaml = ruamel.yaml.YAML()
                   org_data = dict(
                            name=organization.org_name,
                            description=organization.org_description,
                            )
                   with open('input.yml', 'r') as yamlfile:
                       cur_yaml = yaml.load(yamlfile)
                       cur_yaml['organizations'].update(org_data)

                   if cur_yaml:
                       with open('input.yml','w') as yamlfile:
                           yaml.indent(mapping=2, sequence=4, offset=2)
                           yaml.dump(cur_yaml, yamlfile)
    return organization.org_name, organization.org_description

organization()

在 python 脚本的末尾,我的 input.yml 文件应如下所示:

version: x.x.x
is_enterprise: 'true'
license: secrets/license.txt
organizations:
  -  description: xyz
     name: abc
  -  description: pqr
     name: def

但是,每次脚本运行时,它都会覆盖它,而不是将值附加到组织。

我也尝试过使用追加而不是更新,但出现以下错误:

AttributeError: 'CommentedMap' 对象没有属性 'append'

我能做些什么来解决这个问题?

此外,由于我是开发新手,因此任何有关改进此代码的建议都会非常有帮助。

【问题讨论】:

  • 你使用的是哪个 yaml 库?
  • 在帖子中添加了相同的内容。对不起,我是stackoverflow的新手。如果您需要更多信息,请告诉我。

标签: python python-2.7 yaml ruamel.yaml


【解决方案1】:

如果我理解正确,你想要的是cur_yaml['organizations'] += [org_data]。

请注意,如果您多次运行该脚本,您将多次获得相同的条目。

【讨论】:

  • 我尝试添加追加而不是更新,但出现以下错误:- AttributeError: 'CommentedMap' object has no attribute 'append'
  • 您可以通过反复试验编辑您的原始帖子以便我们查看吗?
  • 我用新的上下文更新了答案from ruamel.yaml import YAML
  • 尝试了上述更改。现在我遇到以下错误:- TypeError: += 不支持的操作数类型:'CommentedMap' 和 'list'
【解决方案2】:

使用update 是行不通的,因为键的值 organizations 是一个序列并加载为类似list 的类型 CommentedSeq。所以append-ing 是正确的做法。

这不起作用有点不清楚,因为您没有提供该输入 您开始使用的代码,也不是在执行 appending 时使用的代码 AttributeError CommentedMap。

如果您有一个组织并添加另一个组织,以下是可行的:

import sys
import ruamel.yaml

yaml_str = """\
version: x.x.x
is_enterprise: 'true'
license: secrets/license.txt
organizations:
  -  description: xyz
     name: abc
"""

org_data = dict(
   description='pqr',
   name='def',
)

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4, sequence=4, offset=2)

cur_yaml = yaml.load(yaml_str)
cur_yaml['organizations'].append(org_data)
yaml.dump(cur_yaml, sys.stdout)

这给出了:

version: x.x.x
is_enterprise: 'true'
license: secrets/license.txt
organizations:
  - description: xyz
    name: abc
  - description: pqr
    name: def

如果您还没有组织,请确保您的输入 YAML 如下所示:

version: x.x.x
is_enterprise: 'true'
license: secrets/license.txt
organizations: []

在旧版本的 Python 中,您添加的数据中键的顺序无法保证。到 在旧版本上也执行该命令:

org_data = ruamel.yaml.comments.CommentedMap((('description', 'pqr'), ('name', 'def')))

或

org_data = ruamel.yaml.comments.CommentedMap()
org_data['description'] = 'pqr'
org_data['name'] = 'def'

【讨论】:

  • 我已经用正在使用的代码更新了帖子。尝试添加扩展并得到以下错误: AttributeError: 'CommentedMap' object has no attribute 'extend'
【解决方案3】:

现在发现问题并且工作正常。由于名称和描述是组织的列表对象,我在下面的代码中添加了 [] 并开始工作。

org_data = dict(
    organizations=[dict(
        name=tower_organization.org_name,
        description=tower_organization.org_description,
    )
    ]
)

除了上述之外,我猜 append 不起作用是因为第一个对象中缺少连字符“-”作为标识的一部分。修复上述代码后,append 也可以正常工作了。

谢谢大家的回答。

【讨论】:

    猜你喜欢
    • 2019-02-14
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 2019-09-20
    • 2021-05-03
    • 1970-01-01
    • 2021-08-26
    • 2011-04-28
    相关资源
    最近更新 更多