半扁平化词典

2024-10-03 02:46:30 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有这本字典:

"pools": {
        "JP": {
            "longName": "Jackpot",
            "poolTotal": 318400,
            "shortName": "Jpot",
            "sortOrder": 9
        }
    },

我该如何输出它,这样就可以得到:

pool_JP_longname: Jackpot
pool_JP_poolTotal: 318400
etc
etc

嵌套不应限于2或3个级别,因此应该是通用的。你知道吗

或者另一个例子:

{
    "soccer": {
        "X07": {
            "date": "2013-11-22",
            "poolType": "S10",
            "code": "INT",
            "closeTime": "20:00:00",
            "poolStatus": "OP",
            "pool": {
                "1": {
                    "startRace": 1,
                    "matchs": {
                        "1": {
                            "teamA": "Ajax Cape Town",
                            "teamB": "Moroka Swallows",
                            "matchStatus": "OP"
                        },
                        "2": {
                            "teamA": "Bidvest Wits",
                            "teamB": "MP Black Aces",
                            "matchStatus": "OP"
                        }
                    }
                }
            }
        }
    }
}

看起来像这样:

soccer_X07_data: "2013-11-22"
soccer_X07_poolType: "S10"
etc
soccer_X07_pool_1_matchs_1_teamA
soccer_X07_pool_1_matchs_1_teamB
etc

我开始这样做,但这是不正确的:

def iterTool(json_data, key_string):
    for root_key, item in sorted(json_data.items(), key=itemgetter(0)):
        if type(json_data[root_key]) == dict:
            key_string += "_%s" % root_key
            if json_data[root_key].keys():
                for parent_key in json_data[root_key]:
                    if type(json_data[root_key][parent_key]) in [unicode]:
                        print "%s_%s" % (key_string, parent_key)
                        # print key_string.split("_")
                        # pass
            iterTool(json_data[root_key], key_string)

结果是这样的:

_soccer_X07_code
_soccer_X07_poolStatus
_soccer_X07_closeTime
_soccer_X07_poolType
_soccer_X07_date
_soccer_X07_pool_1_matchs_1_matchStatus
_soccer_X07_pool_1_matchs_1_teamA
_soccer_X07_pool_1_matchs_1_teamB
_soccer_X07_pool_1_matchs_1_10_matchStatus
_soccer_X07_pool_1_matchs_1_10_teamA
_soccer_X07_pool_1_matchs_1_10_teamB
_soccer_X07_pool_1_matchs_1_10_2_matchStatus
_soccer_X07_pool_1_matchs_1_10_2_teamA
_soccer_X07_pool_1_matchs_1_10_2_teamB
_soccer_X07_pool_1_matchs_1_10_2_3_matchStatus
_soccer_X07_pool_1_matchs_1_10_2_3_teamA
_soccer_X07_pool_1_matchs_1_10_2_3_teamB
_soccer_X07_pool_1_matchs_1_10_2_3_4_matchStatus
_soccer_X07_pool_1_matchs_1_10_2_3_4_teamA
_soccer_X07_pool_1_matchs_1_10_2_3_4_teamB
_soccer_X07_pool_1_matchs_1_10_2_3_4_5_matchStatus
_soccer_X07_pool_1_matchs_1_10_2_3_4_5_teamA
...

现在又是一个弧线球。。你知道吗

假设这段话是这样的:

{
    "CAP": {
        "countryName": "ZAF",
        "displayName": "AN"
    },
    "SPA": {
        "countryName": "AUs",
        "displayName": "AG"
    }
}

那么把它弄平是没有意义的,而是:

泛型_键:CAP,公司姓名:ZAF,第姓名:AN你知道吗

你怎么发现这个?你知道吗


Tags: keyjsondatastringetcrootpooljp
3条回答

一个简单的解决方案如下所示:

d = { ... }

def flatten(dic, stack=None):
    if not stack: stack = []
    for key,value in dic.iteritems():
        new_stack = stack[:] + [key]
        if isinstance(value, dict): 
            for result in flatten(value, new_stack):
                yield result
        else: 
            yield new_stack, value

# just print it:           
for stack, value in flatten(d):
    print '{}: {}'.format('_'.join(stack), value)

# create a new dict:
new_d = {'_'.join(stack): value for stack, value in flatten(d)}

这是一个基本的递归问题(或可以用递归解决的问题):

下面是一个符合您的第一个示例的人工示例(或多或少):

d = {
    "pools": {
        "JP": {
            "longName": "Jackpot",
            "poolTotal": 318400,
            "shortName": "Jpot",
            "sortOrder": 9
        }
    }
}


def flattendict(d):
    for k, v in d.items():
        if isinstance(v, dict):
            for x in flattendict(v):
                yield "{}_{}".format(k, x)
        else:
            yield "{}_{}".format(k, v)


for item in flattendict(d):
    print item

注意:我给你留下了几个问题,让你去解决和调查。你知道吗

这将递归地展平词典:

def flatten_dict(dct, output=None, prefix=None):
    if output is None:
        output = {}
    if prefix is None:
        prefix = []
    for key in dct:
        if isinstance(dct[key], dict):
            flatten_dict(dct[key], output, prefix + [key])
        else:
            output["_".join(prefix + [key])] = dct[key]
    return output

第二个例子是:

{'soccer_X07_pool_1_matchs_2_teamA': 'Bidvest Wits', 
 'soccer_X07_pool_1_matchs_2_teamB': 'MP Black Aces',
 'soccer_X07_pool_1_matchs_1_matchStatus': 'OP', 
 ...}

相关问题 更多 >