简体   繁体   中英

How to get a list of dict that each dict is coming from the same original dict with only one key removed?

My scenario: I need to iterate through a nested json object, get return a list of json object, each has one key removed. And you don't know how the original data are structured.

As far as I go: I wrote a recursion function to print every key value in the object. It works. But this is not what I want.

Define return: This function gets a dict and returns a list of dict, each dict is a copy of the original dict after one key removed.

If the dict has 3 keys from the beginning, then I should get 3 dicts each has 1 key removed.

And yes if the key has nested value, they should be removed as well. For example if the key happens to be the root key, then it remains an empty dict.

Here's my code:

def iterate_keys(data: dict):
    # This is as far as I can go
    for key, value in data.items():
        if type(value) in [dict, ]:
            iterate_keys(value)
        elif type(value) in [list, ]:
            for item in value:
                if type(item) in [dict]:
                    iterate_keys(item)
        print(key, value)

# def what_i_really_want(data: dict) -> list:
    # return [dict1, dict2, ...]

if __name__ == '__main__':
    test_dict = {
        "a": "a",
        "c": {
            "c1": [
                {"c11": "c11"},
                {"c12": "c12"},
            ]
        },
    }

    iterate_keys(test_dict)

For the test_dict in the code, ideally it should return list dicts like blow.

result_should_be = [
        {
            # with "a" removed
            "c": {
                "c1": [
                    {"c11": "c11"},
                    {"c12": "c12"},
                ]
            }
        },
        # with "c11" removed
        {
            "a": "a",
            "c": {
                "c1": [
                    {"c12": "c12"},
                ]
            }
        },
        # with "c12" removed
        {
            "a": "a",
            "c": {
                "c1": [
                    {"c11": "c11"},
                ]
            }
        },
        # with "c1" removed
        {
            "a": "a",
            "c": {}
        },
        # with "c" removed
        {
            "a": "a"
        },
    ]

At the end of the day, I'm creating a bunch of test cases. Hope I made myself clear

I have really been struggling with this. Somehow I managed to solve it with two libraries.

The first one jsonpathgenerator gets me all the jsonpath of my original data. It orginally gave me all the 'leaf' item's jsonpath. So I changed the source code a little bit to get every key's jsonpath.

The second one jsonpath_ng let me filter a key with jsonpath.

And with a little bit data manipulation I got the result I was looking for.

This is for if someone ever run into the same situation as me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM