4

次の問題を解決するために何時間も苦労してきましたが、成功しませんでした。

次のようなデータ構造があります。

[   {   'ROOT': [   
            {   'firstElem': 'gc-3/1/0'},
            {   'SecondElem': '5.0.0.1'},
            {   'ThirdElem': '127.3.15.1'},
            {   'index': 16},
            {   'function': 'session'},
            {   'hw': '0.0.0.0'},
            {   'sw': '1.50.1.3'},
            {   'resources': [   {   'cpu-info': [   {   'cpu-peak-load': 1},
                                                     {   'cpu-avg-load': 1}]},
                                 {   'memory-total': 1},
                                 {   'memory-used': 2}]},
            ]},
    {   'ROOT': [
            {   'firstElem': 'gc-4/1/0'},
            {   'SecondElem': '5.0.0.2'},
            {   'ThirdElem': '127.3.4.1'},
            {   'index': 5},
            {   'function': 'stand'},
            {   'hw': '0.0.0.0'},
            {   'sw': '1.50.1.3'},
            {   'resources': [   {   'cpu-info': [   {   'cpu-peak-load': 1},
                                                     {   'cpu-avg-load': 1}]},
                                 {   'memory-total': 1},
                                 {   'memory-used': 2}]},
            ]}
]

このデータ構造をトラバースし、すべての dict-element を同じ名前で結合して、代わりにリストを作成したいと思います。これは説明が難しいので、探している構造の例を作成しました。

{
    "ROOT": [
        {
            "firstElem": "gc-3/1/0", 
            "SecondElem": "5.0.0.1", 
            "ThirdElem": "128.0.2.19", 
            "index": "13", 
            "function": "session", 
            "hw": "1.11.0.0 ", 
            "sw": "1.50.0.228 ", 
            "resources": {
                "cpu-info": {
                    "cpu-peak-load": "1", 
                    "cpu-avg-load": "1",
                }, 
                "memory-total": "1", 
                "memory-used": "2", 
            }, 
        }, 
        {
            "firstElem": "gc-4/1/0", 
            "SecondElem": "5.0.0.1", 
            "ThirdElem": "128.0.2.19", 
            "index": "13", 
            "function": "session", 
            "hw": "1.11.0.0 ", 
            "sw": "1.50.0.228 ", 
            "resources": {
                "cpu-info": {
                    "cpu-peak-load": "8", 
                    "cpu-avg-load": "1", 
                }, 
                "memory-total": "1", 
                "memory-used": "2", 
            },  
        }
    ], 
}

元のデータ構造に固執していて、変更できません。どんな助けでも大歓迎です。上記の構造は単なる例です。データは動的に受信されるため、タグ名はわかりません。そのため、特定のタグ名を使用するソリューションを提供しないでください。

4

4 に答える 4

2

方法は次のとおりです。

>>> from collections import defaultdict
>>> def  combine(item):
    # Easy return if not a list: element itself
    if type(item) != type([]):
        return item
    # else call recursion
    first_ret = [(i.items()[0][0], combine(i.items()[0][1])) for i in item]

    # Here we group by same keys if any ('ROOT', for instance)
    count_keys = defaultdict(list)
    for couple in first_ret:
        count_keys[couple[0]].append(couple[1])
    return dict((k, v if len(v) > 1 else v[0]) for k, v in count_keys.iteritems())

ノードをグループ化するROOT必要がありましたが、機能しているようです。

>>> pprint(combine(l))
{'ROOT': [{'SecondElem': '5.0.0.1',
           'ThirdElem': '127.3.15.1',
           'firstElem': 'gc-3/1/0',
           'function': 'session',
           'hw': '0.0.0.0',
           'index': 16,
           'resources': {'cpu-info': {'cpu-avg-load': 1,
                                      'cpu-peak-load': 1},
                         'memory-total': 1,
                         'memory-used': 2},
           'sw': '1.50.1.3'},
          {'SecondElem': '5.0.0.2',
           'ThirdElem': '127.3.4.1',
           'firstElem': 'gc-4/1/0',
           'function': 'stand',
           'hw': '0.0.0.0',
           'index': 5,
           'resources': {'cpu-info': {'cpu-avg-load': 1,
                                      'cpu-peak-load': 1},
                         'memory-total': 1,
                         'memory-used': 2},
           'sw': '1.50.1.3'}]}
>>> 
于 2013-02-12T17:41:01.047 に答える
2

これを試してみましょう:

r = {}

def lst2dct(lst):
    return (lst if not isinstance(lst, list) else 
        {k: lst2dct(v) for e in lst for k, v in e.items()})

for e in source:
    key, val = e.items()[0]
    r.setdefault(key, []).append(lst2dct(val))
于 2013-02-12T16:54:20.220 に答える
1

少しハックですが、試すことができます:

data = [   {   'ROOT': [   
            {   'firstElem': 'gc-3/1/0'},
            {   'SecondElem': '5.0.0.1'},
            {   'ThirdElem': '127.3.15.1'},
            {   'index': 16},
            {   'function': 'session'},
            {   'hw': '0.0.0.0'},
            {   'sw': '1.50.1.3'},
            {   'resources': [   {   'cpu-info': [   {   'cpu-peak-load': 1},
                                                     {   'cpu-avg-load': 1}]},
                                 {   'memory-total': 1},
                                 {   'memory-used': 2}]},
            ]},
    {   'ROOT': [
            {   'firstElem': 'gc-4/1/0'},
            {   'SecondElem': '5.0.0.2'},
            {   'ThirdElem': '127.3.4.1'},
            {   'index': 5},
            {   'function': 'stand'},
            {   'hw': '0.0.0.0'},
            {   'sw': '1.50.1.3'},
            {   'resources': [   {   'cpu-info': [   {   'cpu-peak-load': 1},
                                                     {   'cpu-avg-load': 1}]},
                                 {   'memory-total': 1},
                                 {   'memory-used': 2}]},
            ]}
]

root_list = [

        ]

final_data = {
            'ROOT' : root_list
            }

for dict in data:
    if dict['ROOT'] not in final_data['ROOT']:
        final_data['ROOT'].append(dict['ROOT'])
于 2013-02-12T16:58:36.290 に答える
0

私はインタープリターであちこちでいくつかのことをしただけで、これを思いつきました:

>>> i = [...] # your data
>>> rdict = {}
>>> for di in i:
 for root in di:
    if root not in rdict:
        rdict[root] = [di[root]]
    else:
        rdict[root] += [di[root]]

rdict必要な dict のタイプであり、複数のリストで動作するはずです。


これの関数バージョン:

def common_dict(list_of_dicts):
    i = list_of_dicts # less typing
    rdict = {}
    for di in i:
        for root in di:
            if root not in rdict:
                rdict[root] = [di[root]]
            else:
                rdict[root] += [di[root]]
return rdict
于 2013-02-12T17:00:59.743 に答える