Skip to content

Instantly share code, notes, and snippets.

@ace0
Created February 26, 2018 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ace0/69350ef62c72c06fe65d8435be860e6a to your computer and use it in GitHub Desktop.
Save ace0/69350ef62c72c06fe65d8435be860e6a to your computer and use it in GitHub Desktop.
"""
Quickly find paths to keys or values deeply embedded in complex structures of JSON.
Written in python 3.
Example:
sampleStructure = {
'AmiLaunchIndex': 0,
'Monitoring': {
'State': 'disabled'
},
'Placement': {
'AvailabilityZone': 'us-east',
'GroupName': '',
'Tenancy': 'default'
}
}
print(search('Tenancy', sampleStructure))
"""
def search(target, structure, variableName="structure"):
"""
Search for a @target key or value in a possibly nested @search.
@return a list of printable strings that show the location and value of the target.
"""
def fmt(path, value):
return "{}{} == {}".format(variableName, strFromPath(path), value)
return [fmt(p,v) for p,v in _searchRecursive(target, structure, [])]
def strFromPath(path):
"""
Construct a string that represents the Python code required to retrieve a value from
the structure.
"""
def fmt(x):
if type(x) == str:
return "['{}']".format(x)
elif type(x) == int:
return "[{}]".format(x)
else:
return x
return ''.join([fmt(x) for x in path])
def _searchRecursive(target, structure, path, debugOutput=False):
"""
Receursively descends a structure in search of a target target or value.
@yields: ([path], value)
"""
if debugOutput:
print("\tSearching: {}".format(path))
# Base case: finding the target in a dcitionary
if type(structure) == dict and target in structure:
yield path + [target], structure[target]
# Base case: matching terminal value
if target == structure:
yield path, target
# Lists
if type(structure) == list:
for i, item in enumerate(structure):
yield from _searchRecursive(target, item, path + [i])
# Dictionaries
if type(structure) == dict:
for k,v in structure.items():
yield from _searchRecursive(target, v, path + [k])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment