Skip to content

Instantly share code, notes, and snippets.

@davehughes
Created July 12, 2017 21:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davehughes/257c4f747bcd6e52f82dc2ebf28de1ec to your computer and use it in GitHub Desktop.
Save davehughes/257c4f747bcd6e52f82dc2ebf28de1ec to your computer and use it in GitHub Desktop.
Flatten simple Python objects to a list of K-V pairs
'''
Flattens a 'JSON' object (really, a simple potentially nested object
composed of dicts, lists, and scalars) into a list of key-value pairs.
Example usage (from http://json.org/example.html):
> import json
> flatten_json(json.loads(SAMPLE_JSON))
[(u'glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso.0', u'GML'),
(u'glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso.1', u'XML'),
(u'glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para',
u'A meta-markup language, used to create markup languages such as DocBook.'),
(u'glossary.GlossDiv.GlossList.GlossEntry.GlossSee', u'markup'),
(u'glossary.GlossDiv.GlossList.GlossEntry.Acronym', u'SGML'),
(u'glossary.GlossDiv.GlossList.GlossEntry.GlossTerm',
u'Standard Generalized Markup Language'),
(u'glossary.GlossDiv.GlossList.GlossEntry.Abbrev', u'ISO 8879:1986'),
(u'glossary.GlossDiv.GlossList.GlossEntry.SortAs', u'SGML'),
(u'glossary.GlossDiv.GlossList.GlossEntry.ID', u'SGML'),
(u'glossary.GlossDiv.title', u'S'),
(u'glossary.title', u'example glossary')]
'''
SAMPLE_JSON = '''
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": [
"GML",
"XML"
]
},
"GlossSee": "markup"
}
}
}
}
}
'''
def join_paths(*args):
return '.'.join([s.strip('.') for s in args if s])
def flatten_json(obj, path_so_far=None):
if type(obj) == dict:
results = []
for k, v in obj.iteritems():
results.extend(flatten_json(v, join_paths(path_so_far, k)))
return results
elif type(obj) == list:
results = []
for idx, v in enumerate(obj):
results.extend(flatten_json(v, join_paths(path_so_far, str(idx))))
return results
else:
return [(path_so_far, obj)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment