Skip to content

Instantly share code, notes, and snippets.

@higarmi
Created September 26, 2013 01:49
Show Gist options
  • Save higarmi/6708779 to your computer and use it in GitHub Desktop.
Save higarmi/6708779 to your computer and use it in GitHub Desktop.
This python recursive function flattens a JSON file or a dictionary with nested lists and/or dictionaries. The output is a flattened dictionary that use dot-chained names for keys, based on the dictionary structure. This allows for reconstructing the JSON structure or converting it to other formats without loosing any structural information.
"""
example: The following JSON document:
{"maps":[{"id1":"blabla","iscategorical1":"0", "perro":[{"dog1": "1", "dog2": "2"}]},{"id2":"blabla","iscategorical2":"0"}],
"masks":{"id":"valore"},
"om_points":"value",
"parameters":{"id":"valore"}}
will have the following output:
{'masks.id': 'valore', 'maps.iscategorical2': '0', 'om_points': 'value', 'maps.iscategorical1': '0',
'maps.id1': 'blabla', 'parameters.id': 'valore', 'maps.perro.dog2': '2', 'maps.perro.dog1': '1', 'maps.id2': 'blabla'}
"""
def flattenDict(d, result=None):
if result is None:
result = {}
for key in d:
value = d[key]
if isinstance(value, dict):
value1 = {}
for keyIn in value:
value1[".".join([key,keyIn])]=value[keyIn]
flattenDict(value1, result)
elif isinstance(value, (list, tuple)):
for indexB, element in enumerate(value):
if isinstance(element, dict):
value1 = {}
index = 0
for keyIn in element:
newkey = ".".join([key,keyIn])
value1[".".join([key,keyIn])]=value[indexB][keyIn]
index += 1
for keyA in value1:
flattenDict(value1, result)
else:
result[key]=value
return result
@subhrajitS
Copy link

@guneysus Use the below code.

def flattenDict(d,result=None,index=None,Key=None):
    if result is None:
        result = {}
    if isinstance(d, (list, tuple)):
        for indexB, element in enumerate(d):
            if Key is not None:
                newkey = Key
            flattenDict(element,result,index=indexB,Key=newkey)            
    elif isinstance(d, dict):        
        for key in d:
            value = d[key]         
            if Key is not None and index is not None:
                newkey = ".".join([Key,(str(key).replace(" ", "") + str(index))])
            elif Key is not None:
                newkey = ".".join([Key,(str(key).replace(" ", ""))])
            else:
                newkey= str(key).replace(" ", "")
            flattenDict(value,result,index=None,Key=newkey)        
    else:
        result[Key]=d        
    return result

In : flattenDict(db)
Out : 
{
'store.bicycle.color': 'red', 
'store.book.author3': 'J. R. R. Tolkien', 
'store.book.category2': 'fiction', 
'store.book.category3': 'fiction', 
'store.book.category0': 'reference', 
'store.book.category1': 'fiction', 
'store.book.price2': 8.99, 
'store.book.price3': 22.99, 
'store.book.price0': 8.95, 
'store.book.price1': 12.99, 
'store.book.title1': 'Sword of Honour', 
'store.book.title0': 'Sayings of the Century', 
'store.book.author1': 'Evelyn Waugh', 
'store.book.author0': 'Nigel Rees', 
'store.book.author2': 'Herman Melville', 
'store.book.title3': 'The Lord of the Rings', 
'store.bicycle.price': 19.95, 
'store.book.title2': 'Moby Dick', 
'store.book.isbn2': '0-553-21311-3', 
'store.book.isbn3': '0-395-19395-8' }

@sauravku
Copy link

sauravku commented Mar 5, 2016

The code doesn't work for me.The output has many missing keys.
Input File = {
"flow": {
"hosts": {
"name": "Client",
"children": [
{
"name": "www.purizon.co.nz",
"children": [
{
"name": "www.purizon.co.nz"
}
]
},
{
"name": "img.oduvanchiksawa.biz",
"children": [
{
"name": "pon.dedulkasanya.biz"
}
]
},
{
"name": "fpdownload2.macromedia.com"
},
{
"name": "ie9cvlist.ie.microsoft.com"
}
]
},
"size": 180
}
}

Output: {u'flow.size': 180, u'flow.hosts.name': u'Client', u'flow.hosts.children.children.name': u'pon.dedulkasanya.biz', u'flow.hosts.children.name': u'ie9cvlist.ie.microsoft.com'}

@zafercavdar
Copy link

Is inverse function available?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment