Home > Software design >  Recursive Function through dict of lists
Recursive Function through dict of lists

Time:03-11

Given this data structure

[{'name': 'Business Operations', 
  'team_edit': ['BusinessOperations'], 
  'team_view': ['Snaptest'], 
  'test_sub_subfolder': [
       {'name': 'test_sub', 
        'team_edit': ['BusinessOperations', 'Freddy'], 
        'team_view': ['hugo']}], 
  'test_sub2_subfolder': [
       {'name': 'test_sub2', 
        'test_sub_subfolder': [
            {'name': 'test_sub_sub', 
             'team_edit': ['BusinessOperations', 'Freddy'], 
             'team_view': ['hugo']}]}]}]

I'm trying to write a recursive function that will give me access to all the elements, essentially printing them out. The nested structure can be of arbitrary length, but will always follow this format.

My first attempt at this is

def recurse_over_object(dict_obj):
    for key, value in dict_obj.items():
        if 'subfolder' in key:
            for pair in recurse_over_object(value[0]):
                print(key, *pair)
                # yield (key, *pair)
        else:
            print(key, value)
            # yield (key, value)

The issue here is that as I go down the tree I call for the value subfolder and go down that route, but in this example I have two subfolders at the same level (test_sub and test_sub2) and I need to get values for both of them.

Does anyone know of any fancy ways to do this ? I can definitely restructure the data input if required to make it easier, for example one idea I had was to make the subfolders on the same level a list but then I was struggling in one recursive function to iterate through those elements.

Any help of ideas would be appreciated.

CodePudding user response:

You could iteratively call recurse_over_object under if 'subfolder' in key:. So like:

def recurse_over_object(dict_obj):
    for key, value in dict_obj.items():
        if 'subfolder' in key:
            for item in value:
                recurse_over_object(item)
        else:
            print(key, value)

Then

for d in data:
    recurse_over_object(d)

outputs:

name Business Operations
team_edit ['BusinessOperations']
team_view ['Snaptest']
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']

CodePudding user response:

To follow your lead on using yield() (as well as print), here is adjusted code that I think will do what your question is asking. Note that the final x = list( ... ) statement is intended to invoke the generator your function creates.

dataStructure = [
    {'name': 'Business Operations', 
     'team_edit': ['BusinessOperations'],
     'team_view': ['Snaptest'], 
     'test_sub_subfolder': [
         {'name': 'test_sub', 
          'team_edit': ['BusinessOperations', 'Freddy'], 
          'team_view': ['hugo']}], 
     'test_sub2_subfolder': [
         {'name': 'test_sub2',
          'test_sub_subfolder': [
              {'name': 'test_sub_sub', 
               'team_edit': ['BusinessOperations', 'Freddy'], 
               'team_view': ['hugo']}]}]}
]
def recurse_over_object(dict_obj):
    for key, value in dict_obj.items():
        if 'subfolder' in key:
            '''
            for pair in recurse_over_object(value[0]):
                print(key, *pair)
                yield (key, *pair)
            '''
            print(key, *list(recurse_over_object(value[0])))
            yield(key, *list(recurse_over_object(value[0])))
        else:
            print(key, value)
            yield (key, value)   

x = list(recurse_over_object(dataStructure[0]))

Output:

name Business Operations
team_edit ['BusinessOperations']
team_view ['Snaptest']
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub2_subfolder ('name', 'test_sub2') ('test_sub_subfolder', ('name', 'test_sub_sub'), ('team_edit', ['BusinessOperations', 'Freddy']), ('team_view', ['hugo']))
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
  • Related