2

私はこのようなpython dictを持っています

{'data': [{'data': [{'data': 'gen1', 'name': 'objectID'},
                   {'data': 'familyX', 'name': 'family'}],
          'name': 'An-instance-of-A'},
         {'data': [{'data': 'gen2', 'name': 'objectID'},
                   {'data': 'familyY', 'name': 'family'},
                   {'data': [{'data': [{'data': '21',
                                        'name': 'objectID'},
                                       {'data': 'name-for-21',
                                        'name': 'name'},
                                       {'data': 'no-name', 'name': None}],
                              'name': 'An-instance-of-X:'},
                             {'data': [{'data': '22',
                                        'name': 'objectID'}],
                              'name': 'An-instance-of-X:'}],
                    'name': 'List-of-2-X-elements:'}],
          'name': 'An-instance-of-A'}],
'name': 'main'}

構造は繰り返され、そのルールは次のようになります。

  • 辞書には「名前」と「データ」が含まれています
  • 「データ」には辞書のリストを含めることができます
  • 「データ」がリストでない場合、それは私が必要とする値です。
  • 「名前」はただの名前です

問題は、各値について、各親のすべての情報を知る必要があることです。

最後に、次のようなアイテムのリストを出力する必要があります。

objectID=gen2 family=familyY An-instance-of-X_objectID=21 An-instance-of-X_name=name-for-21

編集:これは、出力として必要な数行のうちの 1 つにすぎません。「データ」として辞書を持たない各項目に対して、このような 1 行が必要です。

したがって、辞書ではない各データについて、上にトラバースし、情報を見つけて出力します..

itertools や collections のようなモジュールのすべての関数を知っているわけではありません。しかし、そこに私が使用できるものはありますか?これは何と呼ばれていますか (私が自分で研究をしようとしているとき)?

多くの「フラット化辞書」メソッドを見つけることができますが、これは好きではありません。

4

1 に答える 1

3

これは、再帰が適している素晴らしい例です。

input_ = {'data': [{'data': [{'data': 'gen1', 'name': 'objectID'},
                   {'data': 'familyX', 'name': 'family'}],
          'name': 'An-instance-of-A'},
         {'data': [{'data': 'gen2', 'name': 'objectID'},
                   {'data': 'familyY', 'name': 'family'},
                   {'data': [{'data': [{'data': '21',
                                        'name': 'objectID'},
                                       {'data': 'name-for-21',
                                        'name': 'name'},
                                       {'data': 'no-name', 'name': None}],
                              'name': 'An-instance-of-X:'},
                             {'data': [{'data': '22',
                                        'name': 'objectID'}],
                              'name': 'An-instance-of-X:'}],
                    'name': 'List-of-2-X-elements:'}],
          'name': 'An-instance-of-A'}],
'name': 'main'}

def parse_dict(d, predecessors, output):
    """Recurse into dict and fill list of path-value-pairs"""
    data = d["data"]
    name = d["name"]
    name = name.strip(":") if type(name) is str else name
    if type(data) is list:
        for d_ in data:
            parse_dict(d_, predecessors + [name], output)
    else:
        output.append(("_".join(map(str,predecessors+[name])), data))

result = []

parse_dict(input_, [], result)

print "\n".join(map(lambda x: "%s=%s"%(x[0],x[1]),result))

出力:

main_An-instance-of-A_objectID=gen1
main_An-instance-of-A_family=familyX
main_An-instance-of-A_objectID=gen2
main_An-instance-of-A_family=familyY
main_An-instance-of-A_List-of-2-X-elements_An-instance-of-X_objectID=21
main_An-instance-of-A_List-of-2-X-elements_An-instance-of-X_name=name-for-21
main_An-instance-of-A_List-of-2-X-elements_An-instance-of-X_None=no-name
main_An-instance-of-A_List-of-2-X-elements_An-instance-of-X_objectID=22

あなたの要件を正しく理解できたことを願っています。パスを文字列に結合したくない場合は、代わりに先行パスのリストを保持できます。

ご挨拶、

トルステン

于 2012-12-20T11:22:33.517 に答える