-3

I am trying to look up data in nested Python dictionaries by giving a path of keys.

For example, if my dict is

my_dict = {"key1": {"key2": 'my data'}}

I want to access my_dict['key1']['key2'] by giving the path 'key1|key2'

Here is what I tried:

all_keys = "key1|key2"
keys = all_keys.split("|")
key_path = ""
for key in keys:
     key_path += '[\'' + key + '\']'
     #my_dict is a dictionary with other dictionaries within it
     returnval = my_dict + key_path

I am getting the error: TypeError: unsupported operand type(s) for +: 'dict' and 'str'

Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
test_user
  • 69
  • 1
  • 7
  • 1
    `dict` is a type, don't call your variable like this, choose another name – azro Nov 18 '19 at 18:34
  • 2
    question is not clear. what is the intended output here? Please specify your desired input and output clearly – Vishal Nov 18 '19 at 18:34
  • 1
    I *think* you're expecting `dict + key_path` to magically become e.g. `dict['key1']`, which absolutely **will not happen**. You could make and evaluate that string, but why not just `dict[key]`? – jonrsharpe Nov 18 '19 at 18:34
  • @jonrsharpe: I want to make a function that accepts all_keys (keys concatenated using pipe operator) and finds the key value, so I am not directly using dict['key1'] – test_user Nov 18 '19 at 18:41
  • But you seem to be trying, unnecessarily and in a manner that cannot work, to build that expression as a string. The point is you can already use the value of a string as a key, using the notation I showed above. – jonrsharpe Nov 18 '19 at 18:42

3 Answers3

2

You can do that using functools.reduce:

from functools import reduce

nested = {"key1": {"key2": 'my data'}}

all_keys = "key1|key2"
key_path = all_keys.split("|")

data = reduce(lambda dct, key: dct[key], key_path, nested)
print(data)
# my data
Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
0

This is a common beginner problem: confusing language syntax with data. You can do this with the eval function family, but ... don't, as it's prone to painful error. Rather, iterate through your list of keys:

local_val = my_dict   # whatever is at your top level
keys = [ , , ]  # Your list of keys, top-down order
for local_key in keys:
    local_val = local_val[key]

# On loop exit, local_val is the innermost value you referenced.
Prune
  • 76,765
  • 14
  • 60
  • 81
0

dict+'["hello"]["world"]' will throw an error. That is not the way to access dict["hello"]["world"]. The plus symbol doesn't function that way in python, and this is why you're getting the error unsupported operand type(s) for +: 'dict' and 'str'

Python doesn't know how to add a dictionary and a string!

all_keys = "key1|key2" keys = all_keys.split("|") returnval=dict #keep the top level stored in returnval initially for key in keys: returnval=returnval[key] #go down one level print(returnval)

Also, please don't name your dictionary 'dict'. It's also a class name, so it is generally bad practice. Try mydict,d etc.

Eshonai
  • 121
  • 5