您不应在 IMO 假设您的程序名称与您所拥有的程序名称一样简单。如果项目名称变长,转储 YAML 的程序可能会将 project 的标量字符串值包装在多行中。如果名称包含特殊字符(对于 YAML),转储名称的程序将在标量字符串周围使用单引号或双引号。此外,- 可能位于您拥有密钥 project 的行上,而密钥 project 的值不必位于同一行:
- project:
presentations/demo1
description: Some description for demo1 project
YAML 解析器会自动正确地重构这样的标量,除了 YAML 解析器之外,其他任何东西都很难做到这一点。
幸运的是,使用 YAML 解析器很容易在 Python 中检查您想要的内容:
import ruamel.yaml
with open('input.yaml') as fp:
data = ruamel.yaml.safe_load(fp)
for idx, d in enumerate(data[:-1]):
assert d['project'] < data[idx+1]['project']
如果您可以拥有同名的项目,您应该使用<= 而不是<。您必须使用 pip install ruamel.yaml 在您的 virtualenv 中安装 ruamel.yaml(您肯定会使用一个进行开发)。
如果你不只是想检查 YAML,而是生成一个正确排序的,你应该使用:
import ruamel.yaml
with open('input.yaml') as fp:
data = ruamel.yaml.round_trip_load(fp)
ordered = True
for idx, d in enumerate(data[:-1]):
if d['project'] > data[idx+1]['project']:
ordered = False
if not ordered:
project_data_map = {}
for d in data:
project_data_map.setdefault(d['project'], []).append(d)
out_data = []
for project_name in sorted(project_data_map):
out_data.extend(project_data_map[project_name])
with open('output.yaml', 'w') as fp:
ruamel.yaml.round_trip_dump(out_data, fp)
这将保留各个映射/字典中键的顺序,保留任何 cmets。
setdefault().append() 将输入中可能重复/重复的任何项目名称处理为单独的条目。因此,即使某些项目的名称可能相同,输出中的项目数量也会与输入相同。