manav sharma
manav sharma

Reputation: 27

Reducing nested loop size in python

I have Json file which Looks like Below. To get the list (given in example1,example2 and further) , I have to write nested for loop 5-6 times. Is there any easy way to write the code and get the end list ?

Example of Json file

{
"SecureConfig" :[
    {
        "Test" : [
            {
                "Test1" : [
                    {
                        "example1" : ["ls","cat abc.txt | grep wc -l"]
                    },
                    {
                        "example2" : ["ls","cat abc.txt | grep wc -l"]
                    }
                ],
                "Test2" : [
                    {
                        "example3" : ["ls","cat abc.txt | grep wc -l"] 
                    },
                    {
                        "example4" : ["ls","cat abc.txt | grep wc -l"]
                    }
                ]                  
            }
        ]
    }
]}

Loop that I have created is :-

config_file = open(FILE) 
data = json.load(config_file)

for index in range(len(data[module])):
    for ModuelName in data[module][index]:
        ModuleValue=data[module][index][ModuelName]
            for index2 in range(len(ModuleValue)):
                for SubModuleName in ModuleValue[index]:
                    SubModuleValue=ModuleValue[index2][SubModuleName]
                    for index3 in range(len(SubModuleValue)):
                        for keys3 in SubModuleValue[index3]:
                            print (SubModuleValue[index3][keys3])

Upvotes: 1

Views: 67

Answers (1)

fafl
fafl

Reputation: 7385

If you just want to search a nested structure for lists where the first element is a string, then this code will work.

s = """{
"SecureConfig" :[
    {
        "Test" : [
            {
                "Test1" : [
                    {
                        "example1" : ["ls","cat abc.txt | grep wc -l"]
                    },
                    {
                        "example2" : ["ls","cat abc.txt | grep wc -l"]
                    }
                ],
                "Test2" : [
                    {
                        "example3" : ["ls","cat abc.txt | grep wc -l"] 
                    },
                    {
                        "example4" : ["ls","cat abc.txt | grep wc -l"]
                    }
                ]                  
            }
        ]
    }
]}"""

import json

def extract_values(d):
    result = []
    stack = [d]
    while stack:
        node = stack.pop()
        if type(node) is list:
            if len(node) != 0 and type(node[0]) is str:
                result.append(node)
            else:
                for e in node:
                    stack.append(e)
        elif type(node) is dict:
            for v in node.values():
                stack.append(v)
    return result
                

data = json.loads(s)
values = extract_values(data)
for v in values:
    print(v)

This will print

['ls', 'cat abc.txt | grep wc -l']
['ls', 'cat abc.txt | grep wc -l']
['ls', 'cat abc.txt | grep wc -l']
['ls', 'cat abc.txt | grep wc -l']

To also extract the keys, use this instead:

def extract_values(d):
    result = []
    stack = [d]
    while stack:
        node = stack.pop()
        if type(node) is list:
            for e in node:
                stack.append(e)
        elif type(node) is dict:
            for k, v in node.items():
                if type(v) == list and len(v) != 0 and type(v[0]) is str:
                    result.append((k, v))
                else:
                    stack.append(v)
    return result

This will print:

('example4', ['ls', 'cat abc.txt | grep wc -l'])
('example3', ['ls', 'cat abc.txt | grep wc -l'])
('example2', ['ls', 'cat abc.txt | grep wc -l'])
('example1', ['ls', 'cat abc.txt | grep wc -l'])

Upvotes: 1

Related Questions