0

4 つのレベルを持つ yaml 構成ファイルから返された辞書があります。

アイテム、セクション、フィールド、要素

{
    "tag": "test", 
    "sections": [
        {
            "info": "This is section ONE", 
            "tag": "s1"
        }, 
        {
            "info": "This is section TWO", 
            "fields": [
                {
                    "info": "This is field ONE", 
                    "tag": "f1"
                }, 
                {
                    "info": "This is field TWO", 
                    "tag": "f2", 
                    "elements": [
                        {
                            "info": "This is element", 
                            "tag": "e1", 
                            "type_of": "text_field"
                        }, 
                        {
                            "info": "This is element", 
                            "tag": "e2", 
                            "type_of": "text_field"
                        }, 
                        {
                            "info": "This is element", 
                            "tag": "e3", 
                            "type_of": "text_field"
                        }, 
                        {
                            "info": "This is element", 
                            "tag": "e4", 
                            "type_of": "text_field"
                        }
                    ]
                }, 
                {
                    "info": "This is field THREE", 
                    "tag": "f3", 
                    "elements": [
                        {
                            "info": "This is element", 
                            "tag": "e5", 
                            "type_of": "text_field"
                        }, 
                        {
                            "info": "This is element", 
                            "tag": "e6", 
                            "type_of": "text_field"
                        }, 
                        {
                            "info": "This is element", 
                            "tag": "e7", 
                            "type_of": "text_field"
                        }, 
                        {
                            "info": "This is element ONE", 
                            "tag": "e8", 
                            "type_of": "text_field"
                        }
                    ]
                }
            ], 
            "tag": "s2"
        }, 
        {
            "info": "This is section THREE", 
            "fields": [
                {
                    "info": "This is field FOUR", 
                    "tag": "f4"
                }, 
                {
                    "info": "This is field FIVE", 
                    "tag": "f5"
                }, 
                {
                    "info": "This is field SIX", 
                    "tag": "f6"
                }
            ], 
            "tag": "s3"
        }
    ],
    "type_of": "custom"
}

class T():

    def __init__(self):
        self.sections = []
        self.fields = []
        self.elements = []

def rt(y):
    t = T()

    def recurse(y):
        for k,v in y.iteritems(): 
            if isinstance(v, list):
                getattr(t, k).append(v)
                [recurse(i) for i in v]
            else:
                setattr(t, k, v)
    recurse(y)
    return t

したがって、辞書のリストを持つ辞書のリストの辞書を再帰する必要があります。など、それらをタイプに分類し (そして、それが属する部分への参照を追加しますが、一度に 1 つの問題を追加します)、T のインスタンスに入れます。

これは機能しますが、何も削除しません。つまり、各セクションがキャプチャされますが、残りのすべて (フィールド、要素) がキャプチャされます。これはおそらくcomp sci 101ですが、私はほとんど独学なので、このある種のソートアルゴリズムについて学ぶ必要があります。これを改善するためのご意見をお待ちしております。

編集:これは私が予想したよりも詳細であることが判明し、抽象的には、任意のデータ構造を調べて、必要なものまたは必要なものを選択する方法を学ぶ機会が増えました

4

2 に答える 2

0

私が思いついた解決策:

class Tree:
    def __init__(self, node, cargo, parent=None):
        self.node = node
        self.cargo = cargo
        self.parent  = parent
    def __str__(self):
        return str(self.cargo)

from copy import copy
def just_part(y):
    z = copy(y)
    for k,v in z.items():
        if isinstance(v, list):
            del z[k]
    return z

def rt(y):
    tt = []
    s = Tree( id(y), just_part(y) )
    tt.append(s)
    def recurse(y):
        for k,v in y.iteritems(): 
            if isinstance(v, list):
                [tt.append( Tree(id(i), just_part(i), id(y) ) ) for i in v]
                [recurse(i) for i in v]
            else:
                pass
    recurse(y)
    return tt

rt(入れ子になった辞書) を実行するだけで、ノードのリストが返されます。これは、これまでのところ、私がやっていることの開始に適していると思われます。より効果的な方法で達成できることがわかっています。これがあります:http://code.activestate.com/recipes/577982-recursively-walk-python-objects/もありますが、私自身の解決策が今のところ最もpythonicではないかもしれませんが、それはすべてではありません。

于 2012-09-26T15:41:20.123 に答える
0

の要素を再びのsectionsインスタンスにしたいと仮定して、これを試してください。T

def rt(y, levels=1):
    t = T()
    for (k, v) in y.iteritems(): 
        if isinstance(v, list):
            if levels > 0:
                v = [rt(i, levels-1) if isinstance(i, dict) else i for i in v]
                setattr(t, k, v)
        else:
            setattr(t, k, v)
    return t

(辞書以外の要素のリストも考慮し、特定の数の「レベル」の後に反復を停止するように編集されました)

これにより、ネストされたディクショナリが のネストされたインスタンスの階層になりT、ディクショナリ内の項目ごとに属性が作成されます。パラメータを使用するlevelと、再帰の「深さ」を調整できます:level==0アトミック属性のみが含まれるようになるとすぐに。

または、のインスタンスを増やす代わりにの要素を使用t.sectionsする場合:dictsT

def rt(y):
    t = T()
    for (k, v) in y.iteritems(): 
        if isinstance(v, list):
            # remove list elements from dicts in list
            v = [dict((k1, v1) for (k1, v1) in i.iteritems() if not isinstance(v1, list)) 
                 if isinstance(i, dict) else i for i in v]
        setattr(t, k, v)
    return t

これでも思い描いていたものと異なる場合は、 のインスタンスがT辞書でどのように表示されるかを示す具体的な例を提供してください。

于 2012-09-21T14:55:52.693 に答える