0

I have a dictionary in python that represents a directory structure, so something like

dict = {
    "file1.java": {
          "method1": [],
          "method2": []
     },
     "dir1": {
          "file2.java":{
           .
           .
           .
           },
           "dir2": {
                    "file3.java": {
                           "method3": ["hello", "hi"],
                           "method4": []
                    "file4.java": {
            }
     }

}

I also have have a list of strings like

list = ["dir1", "dir2", "file3.java", "method3"]

Is there an easy way to traverse the dictionary to access the data in method3 using the list So I would like to be able to call

dict[list]

and have it do something like

 dict["dir1"]["dir2"]["file3.java"]["method3"]

and return something like

["hello", "hi"]

but I have no idea how long the list of strings will be so the list

list = ["file1.java","method1"]

also needs to work

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • 1
    You can't do that in a vanilla dictionary, but you could either: 1. Create a custom `dict`-like class with a `__getitem__`/`__setitem__` implementation that supports it; or 2. Write a function that takes the dictionary and list of keys. Either way, though, this isn't a code-writing service. – jonrsharpe Jul 07 '15 at 16:53
  • `dict` si a keyword - please do not use it as a variable name! – Nir Alfasi Jul 07 '15 at 16:53
  • 2
    Probable duplicate: http://stackoverflow.com/q/14692690/3001761 – jonrsharpe Jul 07 '15 at 16:54
  • @alfasin not a keyword, strictly speaking, but it's certainly wisest not to shadow it! – jonrsharpe Jul 07 '15 at 16:56
  • @jonrsharpe how would I write a function that would accomplish it though. I guess i realized it wouldn't be in vanilla python, but I am unsure how to do it for myself – pythonHelpRequired Jul 07 '15 at 16:56
  • **This isn't a code-writing service** - what have you tried, and what exactly is the problem with it? – jonrsharpe Jul 07 '15 at 16:57
  • @jonrsharpe thanks for the correction! what is the right term then ? – Nir Alfasi Jul 07 '15 at 16:59
  • @alfasin I usually describe it as *"the name of a built-in [function/type/whatever they're shadowing]"*. – jonrsharpe Jul 07 '15 at 17:00
  • @jonrsharpe I think I see the distinction, since this is a (builtin) function and not a "keyword" such as `if` `while` etc, is that correct ? – Nir Alfasi Jul 07 '15 at 17:01
  • 1
    @alfasin yes, exactly - the keywords (see e.g. https://docs.python.org/2/reference/lexical_analysis.html#keywords, https://docs.python.org/2/library/keyword.html) can't be assigned to at all, hence can't be shadowed. – jonrsharpe Jul 07 '15 at 17:02

2 Answers2

1

You can use the reduce built-in function.

db = {
    "file1.java": {
          "method1": [],
          "method2": []
     },
     "dir1": {
           "dir2": {
                    "file3.java": {
                           "method3": ["hello", "hi"],
                           "method4": []
                    },
                    "file4.java": {
                    }
            }
     }

}

def lookup(db, path):
    return reduce(dict.get, path, db)

print lookup( db, ["dir1", "dir2", "file3.java", "method3"] )


print lookup( db, ["file1.java","method1"] )
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
0

You can take advantage of the fact that dicts and arrays are reference types to do something like this...

current_entry = dict
for item in list:
    current_entry = current_entry[item]

# The element you want is now in current_entry

Of course, add appropriate error checking to make sure you don't try and select a dict element that doesn't exist.

canton7
  • 37,633
  • 3
  • 64
  • 77