如何对具有100条痕迹的高度嵌套对象进行适度修改?

2024-09-30 16:34:45 发布

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

我有一个臃肿的嵌套字典a我想转换成一个简洁的、嵌套较少的字典B,希望变成JSON。从设计角度来看,这可以通过以下几种方式实现:

开关筛

一种方法是遍历A并通过一系列复杂的switch语句将数据筛选成B的形状。如果A相对较大,这是不好的,因为这将需要许多开关条件,或者如果一个具有许多不同的膨胀结构,如A并且需要组成许多不同的开关筛。如果跟踪(指向最深嵌套值的任何breadcrumb路径)通过a将来的更改,这也是不好的。”唯一不变的是“变化”,尽管这是大多数方法的问题

地图转换器

我推测另一种方法是,在行走A时,使用一个查找表,将A中所有可能的跟踪映射到表示和构建B的每个新跟踪上。换句话说,A中每个记录道的每个值都映射为B中各个记录道的值。看看this example。要做到这一点,需要与在开关筛选器中筛选数据所需的AB转换逻辑的知识相同,但使转换作为查找表具有很高的可读性。这种方法的缺点是,如果A的结构发生更改,并且查找表不包含新的/更改的跟踪大小写,则很容易中断

地图筛选器

我推测,也许更好的方法是前两种方法的混合,即使用查找表将a的所有已知记录道转换为B,然后根据a可能改变的某些已知规则,使用切换逻辑来处理新的记录道。当然,如果A的结构发生剧烈变化,那么所有的赌注都将落空

问题

我倾向于找到一些例子,并编写了许多开关筛选器来修改数据结构。我从来没有做过映射变压器映射筛选器,我想知道它们在试图简化许多高度嵌套的冗余结构的情况下是否有效,每个结构可能有200多条记录道。我正在考虑建立一个地图筛选器(如果它已经有名字的话,也可以叫它什么)。有没有更好的方法来转换JSON

我在用Python工作(如果你知道有一个库可以帮助我的话)。下面是使用Map Transformer(如果这是一种可行的方法)的启动代码

import json

def recurse(d, keys=[]):
    # walk python object. Thanks to NeilenMarais @ http://stackoverflow.com/questions/8335096/iterate-over-nested-dictionary
    if isinstance(d, dict):
        for k in d:
            for rv in recurse(d[k], keys + [(k,type(d).__name__)]):
                yield rv
    elif isinstance(d, list):
        for i, v in enumerate(d):
            for rv in recurse(v, keys + [(i,type(d).__name__)]):
                yield rv
    else:
        yield (keys, d)

def pp_json(json_thing, sort=True, indents=4):
    # pretty print jsonesque object
    if type(json_thing) is str:
        print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents))
    else:
        print(json.dumps(json_thing, sort_keys=sort, indent=indents))
    return None

aLongFluffyJson="""{
    "anAlrightKey1": "21.5",
    "key2": {
        "superfluousKey1":{
            "keyWhosNameIsTooLong1": "1",
            "keyWhosNameIsTooLong2": "2013-08-28",
            "anAlrightKey2": "435 PACIFIC AVENUE, 4TH FLOOR"
        }
    },
    "key3": [
        {
            "keyWhosNameIsTooLong3": "200045",
            "anAlrightKey3": "PeoplePlacesThings"
        },
        {
            "keyWhosNameIsTooLong3": "300045",
            "anAlrightKey3": "null"
        }
    ],
    "key4": {
        "key5": {
            "key6": "thisValueDoesntMatter",
            "key7": "iWishToBeAccessible"
        }
    }
}"""

aConciseJson="""{
        "anAlrightKey1": "21.5",
        "key2": {
                "keyNowShort1": "true",
                "keyNowShort2": "2013-08-28"
        },
        "key3": [
                {
                        "keyNowShort3": "200045",
                        "anAlrightKey3": "PeoplePlacesThings"
                },
                {
                        "keyNowShort4": "300045"
                }
        ],
        "key4": {
                "key5": {
                        "key6": "iWishToBeAccessible",
                        "key7": "iAlsoWishToBeAccessible",
                        "anAlrightKey2": "435 PACIFIC AVENUE, 4TH FLOOR"
                }
        }
}"""

aLongFluffyJson=json.loads(aLongFluffyJson)

aConciseJson=json.loads(aConciseJson)

pp_json(aConciseJson) #See what you're working with

# prepare what could be used to build the lookup table in a Map Transformer
for compound_key, val in recurse(aLongFluffyJson):
    print('{}: {}'.format(compound_key, val))    
print(" ")
for compound_key, val in recurse(aConciseJson): #this is missing the value type definition
    print('{}: {}'.format(compound_key, val))

Tags: 方法injsonfortype记录keyssort