2

我有一个名为的 YAML 文件input.yaml

---
'001':
  name: Ben
  email: ben@test.com
'002':
  name: Lisa
  email: lisa@test.com
'003':
  name: Alex
  email: alex@test.com
.
.
.

我有一本字典:

my_dict = {'001': '000-111-2222', '002': '000-111-2223', '003': '000-111-2224', ...}

我想要一个名为的更新文件output.yaml,如下所示:

---
'001':
  name: Ben
  email: ben@test.com
  phone: 000-111-2222
'002':
  name: Lisa
  email: lisa@test.com
  phone: 000-111-2223
'003':
  name: Alex
  email: alex@test.com
  phone: 000-111-2224
.
.
.

请注意输出文件如何在“电话”字段中添加来自匹配键的字典值的值。

我如何获得这样的文件?...我已经尝试了各种。

4

2 回答 2

3

如果您担心文件的格式保持不变(并且如果有应保留的注释),您可以执行以下操作:

import ruamel.yaml

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.explicit_start = True

with open('input.yaml') as fp:
    data = yaml.load(fp)

my_dict = {
    '001': '000-111-2222',
    '002': '000-111-2223',
    '003': '000-111-2224',
}

for k in my_dict:
    data.setdefault(k, {})['phone'] = my_dict[k]

with open('output.yaml', 'w') as fp:
    yaml.dump(data, fp)

之后output.yaml包含:

---
'001':
  name: Ben
  email: ben@test.com
  phone: 000-111-2222
'002':
  name: Lisa
  email: lisa@test.com
  phone: 000-111-2223
'003':
  name: Alex
  email: alex@test.com
  phone: 000-111-2224

笔记:

  1. yaml.preserve_quotes = True并不是真正必要的,因为需要引号的标量(您的字符串以零开头)单引号是默认的,并且您的输入中也没有多余的引号。

  2. 我使用而不是像@Aaron 在他的来源中建议的那样data.setdefault(k, {})['phone']检查是否存在。如果密钥不在,data[k]它将创建一个(空)dict 。kdata

  3. 如果您只想更新匹配for的键,请在循环中使用以下内容:

    try:
        data[k]['phone'] = my_dict[k]
    except KeyError:
        pass
    
  4. 您需要在文档开始时yaml.explicit_start = True获取。不会自动保留它。如果您还需要文档结束标记 ( ),请使用:---ruamel.yaml...yaml.explicit_end = True

  5. 如果您希望电话号码出现在 和 之间name,请email使用:

    data.setdefault(k, {}).insert(1, 'phone', my_dict[k])
    

    这使:

    ---
    '001':
      name: Ben
      phone: 000-111-2222
      email: ben@test.com
    '002':
      name: Lisa
      phone: 000-111-2223
      email: lisa@test.com
    '003':
      name: Alex
      phone: 000-111-2224
      email: alex@test.com
    

    (即0表示在第一个键1之前插入,在第二个键之前插入等)

于 2018-04-18T06:49:13.040 回答
1

除了读取和写入文件之外,也许这会为您指明正确的方向:

import yaml


document = """
---
'001':
  name: Ben
  email: ben@test.com
'002':
  name: Lisa
  email: lisa@test.com
'003':
  name: Alex
  email: alex@test.com
"""

phones = {'001': '000-111-2222', '002': '000-111-2223', '003': '000-111-2224'}

doc = yaml.safe_load(document)

for k, v in phones.items():
    # Might want to check that 'doc[k]' exists
    doc[k]['phone'] = v

print(yaml.safe_dump(doc, default_flow_style=False, explicit_start=True))

输出:

'001':
  email: ben@test.com
  name: Ben
  phone: 000-111-2222
'002':
  email: lisa@test.com
  name: Lisa
  phone: 000-111-2223
'003':
  email: alex@test.com
  name: Alex
  phone: 000-111-2224
于 2018-04-17T21:41:59.840 回答