Skip to main content
 首页 » 编程设计

python之PyYaml 向后倾倒东西

2025年05月04日9dflying

所以我有一个 yaml 文件,里面有很多琐碎的问题和一个答案列表。但是,每当我尝试加载此文件并使用 pyyaml 将内容转储到 python 中时,它都会向后转储它们。我不确定这是我的 yaml 文件还是我对库做错了什么。

假设我的一对问题/答案在 yaml 文件中看起来像这样 -

{"question": "What is the name of this sequence of numbers: 1, 1, 2, 3, 5, 8, 13, ...",  
 "answer": ["The Fibonacci Sequence", "The Padovan Sequence", "The Morris Sequence"]} 

当我在那个 python 字典上使用 yaml.dump() 时,它会转储这个 -

answer: [fibonacci, padovan, morris]\nquestion: 'what sequence is this: 1, 1, 2, 3, 5, 8, 13, ...'\n" 

我在期待这个-

- question: "What is the name of this sequence of numbers: 1, 1, 2, 3, 5, 8, 13, ..." 
  answer: ["The Fibonacci Sequence", "The Padovan Sequence", "The Morris Sequence"] 

我是不是做错了什么?

请您参考如下方法:

我在这里有一些不同的答案。如果元素的顺序对您来说除了可读性之外的其他原因很重要,dbaupp 的答案是正确的。如果您希望问题在答案之前出现的唯一原因是使文件更易于阅读,那么您不需要使用 !!omap,而是可以使用自定义表示来获得您想要的顺序。

首先,前面没有 - 的转储器转储问题是因为您只转储单个映射,而不是它们的列表。将您的字典放入列表中,这将得到修复。所以我们开始:

d = [{"question": "What is the name of this sequence of numbers: 1, 1, 2, 3, 5, 8, 13, ...",  
 "answer": ["The Fibonacci Sequence", "The Padovan Sequence", "The Morris Sequence"]}] 

现在我们有一个我们希望输出的特定顺序,所以我们将指定它,并使用该顺序转换为 OrderedDict:

from collections import OrderedDict 
order = ['question', 'answer'] 
do = [ OrderedDict( sorted( z.items(), key=lambda x: order.index(x[0]) ) ) for z in d ] 

接下来,我们需要让 PyYAML 知道如何处理 OrderedDict。在这种情况下,我们不希望它是一个 !!omap,我们只想要一个具有特定顺序的映射。对于我不清楚的一些动机,如果你给 dumper.represent_mapping 一个字典,或者任何具有 items 属性的东西,它会在转储之前对项目进行排序,但是如果你给它输出 items() (例如,一个列表(键, value) 元组),它不会。因此我们可以使用

def order_rep(dumper, data): 
    return dumper.represent_mapping( u'tag:yaml.org,2002:map', data.items(), flow_style=False ) 
yaml.add_representer( OrderedDict, order_rep ) 

然后,print yaml.dump(do) 的输出结果为:

- question: 'What is the name of this sequence of numbers: 1, 1, 2, 3, 5, 8, 13, ...' 
  answer: [The Fibonacci Sequence, The Padovan Sequence, The Morris Sequence] 

有许多不同的方法可以做到这一点。实际上根本不需要使用 OrderedDict,您只需要问题/答案对属于您可以为其编写代表的某个类。

再次强调,这只是为了人类可读性和审美目的。此处的顺序将没有任何 YAML 意义,就像您使用 !!omap 一样。看起来这对您来说主要是为了提高可读性。