如何使用来自另一个字典中匹配键的值更新 YAML 文件?
How to update YAML file with value coming from a matching key in another dictionary?
我有一个名为 input.yaml
的 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
.
.
.
请注意输出文件如何添加 "phone" 字段以及来自匹配键的字典值的值。
如何获得这样的文件? ... 各种都试过了
除了读取和写入文件之外,也许这会为您指明正确的方向:
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
如果您担心文件的格式保持不变(并且如果有注释应该保留),您可以这样做:
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
备注:
yaml.preserve_quotes = True
并不是真正必要的,因为对于需要引号的标量(您的字符串以零开头)单引号是默认的,并且您的输入中也没有多余的引号.
我使用 data.setdefault(k, {})['phone']
而不是检查 data[k]
是否存在,正如@Aaron 在他的来源中所建议的那样。如果键 k
不在 data
.
中,它将创建一个(空)字典
如果您只想更新 匹配的 键,则在 for
循环中使用以下内容:
try:
data[k]['phone'] = my_dict[k]
except KeyError:
pass
您需要 yaml.explicit_start = True
才能在文档开头获得 ---
。 ruamel.yaml
不会自动保留它。如果您还需要文档结束标记 (...
),请使用:yaml.explicit_end = True
如果你想让phone号出现在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
在第二个键之前等)
我有一个名为 input.yaml
的 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
.
.
.
请注意输出文件如何添加 "phone" 字段以及来自匹配键的字典值的值。
如何获得这样的文件? ... 各种都试过了
除了读取和写入文件之外,也许这会为您指明正确的方向:
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
如果您担心文件的格式保持不变(并且如果有注释应该保留),您可以这样做:
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
备注:
yaml.preserve_quotes = True
并不是真正必要的,因为对于需要引号的标量(您的字符串以零开头)单引号是默认的,并且您的输入中也没有多余的引号.我使用
data.setdefault(k, {})['phone']
而不是检查data[k]
是否存在,正如@Aaron 在他的来源中所建议的那样。如果键k
不在data
. 中,它将创建一个(空)字典
如果您只想更新 匹配的 键,则在
for
循环中使用以下内容:try: data[k]['phone'] = my_dict[k] except KeyError: pass
您需要
yaml.explicit_start = True
才能在文档开头获得---
。ruamel.yaml
不会自动保留它。如果您还需要文档结束标记 (...
),请使用:yaml.explicit_end = True
如果你想让phone号出现在
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
在第二个键之前等)