CMinusMinus
CMinusMinus

Reputation: 456

Recursively find elements in dictionary using an array in Python

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

Upvotes: 2

Views: 337

Answers (5)

Marat
Marat

Reputation: 15738

Simple, yet handling missing keys + no recursion

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

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

Upvotes: 0

Stanislav Nosulenko
Stanislav Nosulenko

Reputation: 194

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

Upvotes: 2

Mateo Lara
Mateo Lara

Reputation: 927

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

Upvotes: 1

John Gordon
John Gordon

Reputation: 33335

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)

Upvotes: 1

Andy Delworth
Andy Delworth

Reputation: 157

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.

Upvotes: 2

Related Questions