pythonlistdictionarynested-loopsliterate-programming

How to iterate a mixed of nested list and dict and filter items


I have an example object which is mixed of lists and dicts:

{
    "field_1" : "aaa",
    "field_2": [
        {
        "field_3" : "bbb",
          .....
        "field_4" : "ccc",
        "field_need_to_filter" : False,
    },

        {
        "field_5" : "ddd",
          .....
        "field_6": [
            {
            "field_7" : "eee",
            ....
            "field_8" : [
                {
                "field_9": "fff",
                .....
                "field_10": {
                    "field_11": "rrr",
                    ...
                    "field_12": [
                        {
                        "field_13": "xxx",
                        ...
                        "field_need_to_filter": True,
                        },
                        {
                        "field_13": "yyy",
                        ...
                        "field_need_to_filter": True,
                        },
                        {
                        "field_13": "zzz",
                        ...
                        "field_need_to_filter": False,
                        }
                                ]
                                }
                },


        ]}]}

       ]
}

I'd like to iterate it and add all the corresponding values for field_13 where field_need_to_filter is True, so for this example, expected output would be: ["xxx", "yyy"]


Solution

  • Try recursion:

    dct = {
        "field_1": "aaa",
        "field_2": [
            {
                "field_3": "bbb",
                "field_4": "ccc",
                "field_need_to_filter": False,
            },
            {
                "field_5": "ddd",
                "field_6": [
                    {
                        "field_7": "eee",
                        "field_8": [
                            {
                                "field_9": "fff",
                                "field_10": {
                                    "field_11": "rrr",
                                    "field_12": [
                                        {
                                            "field_13": "xxx",
                                            "field_need_to_filter": True,
                                        },
                                        {
                                            "field_13": "yyy",
                                            "field_need_to_filter": True,
                                        },
                                        {
                                            "field_13": "zzz",
                                            "field_need_to_filter": False,
                                        },
                                    ],
                                },
                            },
                        ],
                    }
                ],
            },
        ],
    }
    
    
    def find(o, key):
        if isinstance(o, dict):
            if key in o and o.get("field_need_to_filter"):
                yield o[key]
    
            for v in o.values():
                yield from find(v, key)
        elif isinstance(o, list):
            for v in o:
                yield from find(v, key)
    
    
    out = list(find(dct, "field_13"))
    print(out)
    

    Prints:

    ['xxx', 'yyy']