Recursively find elements in dictionary using an array in Python

Viewed 194

I have an array:

["a", "1", "2"]

and a kinda complex dictionary:

{
  "a":{
    "1": {
      "1": "Some text",
      "2": "This is the text I want",
      "3": "Even more"
    },
    "2": {
      "1": "Some text",
      "2": "More text"
    }
  },
  "b": {
    "1": "Here is some text",
    "2": {
      1: "Some text"
    },
    "3": {}
  }
}

How can I use my array, to get "This is the text I want"? I'm new to recursion, so I don't really know how to solve this problem correctly

5 Answers

Since the array is in the correct order, at each recursive step you want to use the front of the list to get the next-most-inner dictionary. Something like this:

def get_dict(arr, d):
    if not arr:
        return d
    return get_dict(arr[1:], d[arr[0]])

A more efficient way would be to reverse the array at the begining, and then take elements from the end, because taking elements from the end is constant time, while taking them from the front is linear (must shift everything over). If you do this, make sure to only reverse it once before the recursion begins.

This should be a bit easier:

keys = ["a", "1", "2"]
dictionary = {
  "a":{
    "1": {
      "1": "Some text",
      "2": "This is the text I want",
      "3": "Even more"
    },
    "2": {
      "1": "Some text",
      "2": "More text"
    }
  },
  "b": {
    "1": "Here is some text",
    "2": {
      1: "Some text"
    },
    "3": {}
  }
}

for key in keys: # drop to lower level of dictionary with each loop
    try:
        dictionary = dictionary[key]
    except KeyError:
        dictionary = 'ERROR'
        break
    
print(dictionary) # after the loop ends, 'dictionary' will hold the required value

No need for recursion. A for loop is all you need.

array = ["a", "1", "2"]
data = { ... complex data here ... }

current_data = data

for key in array:
    current_data = current_data[key]

print(current_data)

This worked for me:

address = ["a", "1", "2"]
dict_addresses = {
    "a": {
        "1": {
            "1": "Some text",
            "2": "This is the text I want",
            "3": "Even more"
        },
        "2": {
            "1": "Some text",
            "2": "More text"
        }
    },
    "b": {
        "1": "Here is some text",
        "2": {
            1: "Some text"
        },
        "3": {}
    }
}


def recurse(dict_addresses, address, counter=0):
    if counter == len(address):
        return(dict_addresses)
    dict_addresses = dict_addresses[address[counter]]
    return(recurse(dict_addresses, address, counter + 1, ))


result = recurse(dict_addresses, address)
print(result)

Output:

This is the text I want

Simple, yet handling missing keys + no recursion

data, path = {...}, ["a", "1", "2"]

while data and path:
    data = data.get(path.pop(0))
Related