1

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])
4
  • 1
    Welcome back to Stack Overflow. As a refresher, please read How to Ask and minimal reproducible example. This question is not clear. What does "end list of data" mean? What should the result be when you have this input, and why? What code did you try using, and why does it have loops at all, let alone deeply nested ones? Also, please do not upload images of data when asking a question.. Instead, copy and paste the JSON example with proper formatting as a multi-line code block. Commented Jul 30, 2022 at 3:38
  • Updated the question as per your recommendation. Hope it's clear now. Let me know if still something is clear. Commented Aug 2, 2022 at 8:50
  • If this is not a debugging request, then please make sure that others can copy and paste the code, use it on the example input, and get the correct result. Also show what the result should be. I guess you are trying to get all the ["ls","cat abc.txt | grep wc -l"] values, but not sure if I have that right, whether you want to take separate strings from those lists, etc. Also, do you really want to print everything, or would it be better to make a flat list of the results? Commented Aug 2, 2022 at 20:43
  • Does stackoverflow.com/questions/2544055 answer your question? Or stackoverflow.com/questions/47367665 ? Commented Aug 2, 2022 at 20:46

1 Answer 1

1

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'])
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the reply. Really appreciate your help. Is there a way i can get name of key as well , like --- key for value ['ls', 'cat abc.txt | grep wc -l'] is example1. By using pop function , we are losing the track of keys for the corresponding values.
Sure, added the code
Works perfect for my requirement. Thanks a lot for your help. My whole code looks good now. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.