1

だから私はたくさんの雑学クイズと答えのリストを含むyamlファイルを持っています。ただし、このファイルをロードして、pyyamlを使用してPythonでコンテンツをダンプしようとすると、逆方向にダンプされます。それが私のyamlファイルなのか、それともライブラリで何か問題が発生しているのかわかりません。

私の質問と回答のペアの1つが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"]

私はここで何か間違ったことをしていますか?

4

4 に答える 4

6

ここで少し違う答えがあります。読みやすさ以外の理由で要素の順序が重要である場合、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にdict、またはitems属性を持つものを指定すると、ダンプする前にアイテムが並べ替えられますが、items()の出力(たとえば、(keyのリスト)を指定すると、 、値)タプル)、そうではありません。したがって、私たちは使用することができます

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を使用することは実際にはまったく必要ありません。必要なのは、質問と回答のペアが、表現者を記述できるクラスのものである必要があることだけです。

繰り返しになりますが、これは人間の読みやすさと美的目的のためだけであることを理解してください。ここでの順序は、!! omapを使用している場合のように、YAMLの重要性はありません。これは読みやすさのためにあなたにとって主に重要であるように見えました。

于 2012-12-22T10:38:03.270 に答える
4

ダンプで優先される場合は、以下のコードを使用できます

import yaml

class MyDict(dict):
   def to_omap(self):
      return [('question', self['question']), ('answer', self['answer'])]

def represent_omap(dumper, data):
   return dumper.represent_mapping(u'tag:yaml.org,2002:map', data.to_omap())

yaml.add_representer(MyDict, represent_omap)

questions = [
   MyDict({'answer': 'My name is Bob.', 'question': 'What is your name?'}),
   MyDict({'question': 'How are you?', 'answer': 'I am fine.'}),
]
print yaml.dump(questions, default_flow_style=False)

出力は次のとおりです。

- question: What is your name?
  answer: My name is Bob.
- question: How are you?
  answer: I am fine.
于 2013-06-26T01:34:41.880 に答える
2

YAML連想配列(およびPython辞書)は、要素の順序を保持しません。

ただし、順序がインポートの場合、YAMLは順序付きマップ!!omapを定義します。PyYAMLはデフォルトでタプルのリストに解析します。例:

>>> yaml.load('''!!omap
... - a: foo
... - b: bar''')
[('a','foo'),('b','bar')]

この回答は、 PythonOrderedDict!!omapにそれらをロードする方法に関する詳細を提供します。

于 2012-03-31T00:30:54.743 に答える
1

それらを辞書としてロードする場合、それらの順序は任意です。辞書は注文されたコンテナではありません。

于 2012-03-31T00:15:20.997 に答える