Convert Dot notation string into nested Python object with Dictionaries and arrays










2















Background



For some background, I'm trying to create a tool that converts worksheets into API calls using Python 3.5



For the conversion of the table cells to the schema needed for the API call, I've started down the path of using javascript like syntax for the headers used in the spreadsheet. e.g:



Worksheet Header (string)



dict.list[0].id


Python Dictionary




"dict":
"list": [
"id": "my cell value"
]



It's also possible that the header schema could have nested arrays/dicts:



one.two[0].three[0].four.five[0].six


And I also need to append to the object after it has been created as I go through each header.



What I've tried



add_branch



Based on https://stackoverflow.com/a/47276490/2903486 I am able to get nested dictionaries setup using values like one.two.three.four and I'm able to append to the existing dictionary as I go through the rows but I've been unable to add in support for arrays:



def add_branch(tree, vector, value):
key = vector[0]
tree[key] = value
if len(vector) == 1
else add_branch(tree[key] if key in tree else ,
vector[1:],
value)
return tree

file = Worksheet(filePath, sheet).readRow()
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList


My own version of add_branch



import re, json
def branch(tree, vector, value):
"""
Used to convert JS style notation (e.g dict.another.array[0].id) to a python object
Originally based on https://stackoverflow.com/a/47276490/2903486
"""

# Convert Boolean
if isinstance(value, str):
value = value.strip()

if value.lower() in ['true', 'false']:
value = True if value.lower() == "true" else False

# Convert JSON
try:
value = json.loads(value)
except:
pass

key = vector[0]
arr = re.search('[([0-9]+)]', key)
if arr:
arr = arr.group(0)
key = key.replace(arr, '')
arr = arr.replace('[', '').replace(']', '')

newArray = False
if key not in tree:
tree[key] =
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:
isInArray = False
for x in tree[key]:
if x.get(vector[1:][0], False):
isInArray = x[vector[1:][0]]

if isInArray:
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:

tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))

if len(vector) == 1 and len(tree[key]) == 1:
tree[key] = value.split(",")
else:
tree[key] = value
if len(vector) == 1
else branch(tree[key] if key in tree else ,
vector[1:],
value)
return tree


What still needs help



My branch solution works pretty well actually now after adding in some things but I'm wondering if I'm doing something wrong/messy here or if theres a better way to handle where I'm editing nested arrays (my attempt started in the if IsInArray section of the code)



I'd expect these two headers to edit the last array, but instead I end up creating a duplicate dictionary on the first array:



file = [
"one.array[0].dict.arrOne[0]": "1,2,3",
"one.array[0].dict.arrTwo[0]": "4,5,6"
]
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList


Outputs:



[

"one":
"array": [

"dict":
"arrOne": [
"1",
"2",
"3"
]

,

"dict":
"arrTwo": [
"4",
"5",
"6"
]


]


]


Instead of:



[

"one":
"array": [

"dict":
"arrOne": [
"1",
"2",
"3"
],
"arrTwo": [
"4",
"5",
"6"
]


]


]









share|improve this question



















  • 1





    Maybe I missed a detail here, but how does your string indicate the list index position of any selector that follows? For example in "dict.list.id": if list looks like ['id': 1, 'id': 2] how do you know which id you are referring to?

    – benvc
    Nov 12 '18 at 21:23












  • @benvc yeah thats one thing i was trying to figure out myself (maybe by putting that in the header e.g. list[0].id or by checking if the indicator is an int like list.1.id -- was hoping it could be something like the last, but haven't figured that out entirely

    – Aneuway
    Nov 12 '18 at 21:32











  • edit: added a better version of the add_branch method that (almost) handles arrays properly

    – Aneuway
    Nov 14 '18 at 15:19















2















Background



For some background, I'm trying to create a tool that converts worksheets into API calls using Python 3.5



For the conversion of the table cells to the schema needed for the API call, I've started down the path of using javascript like syntax for the headers used in the spreadsheet. e.g:



Worksheet Header (string)



dict.list[0].id


Python Dictionary




"dict":
"list": [
"id": "my cell value"
]



It's also possible that the header schema could have nested arrays/dicts:



one.two[0].three[0].four.five[0].six


And I also need to append to the object after it has been created as I go through each header.



What I've tried



add_branch



Based on https://stackoverflow.com/a/47276490/2903486 I am able to get nested dictionaries setup using values like one.two.three.four and I'm able to append to the existing dictionary as I go through the rows but I've been unable to add in support for arrays:



def add_branch(tree, vector, value):
key = vector[0]
tree[key] = value
if len(vector) == 1
else add_branch(tree[key] if key in tree else ,
vector[1:],
value)
return tree

file = Worksheet(filePath, sheet).readRow()
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList


My own version of add_branch



import re, json
def branch(tree, vector, value):
"""
Used to convert JS style notation (e.g dict.another.array[0].id) to a python object
Originally based on https://stackoverflow.com/a/47276490/2903486
"""

# Convert Boolean
if isinstance(value, str):
value = value.strip()

if value.lower() in ['true', 'false']:
value = True if value.lower() == "true" else False

# Convert JSON
try:
value = json.loads(value)
except:
pass

key = vector[0]
arr = re.search('[([0-9]+)]', key)
if arr:
arr = arr.group(0)
key = key.replace(arr, '')
arr = arr.replace('[', '').replace(']', '')

newArray = False
if key not in tree:
tree[key] =
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:
isInArray = False
for x in tree[key]:
if x.get(vector[1:][0], False):
isInArray = x[vector[1:][0]]

if isInArray:
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:

tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))

if len(vector) == 1 and len(tree[key]) == 1:
tree[key] = value.split(",")
else:
tree[key] = value
if len(vector) == 1
else branch(tree[key] if key in tree else ,
vector[1:],
value)
return tree


What still needs help



My branch solution works pretty well actually now after adding in some things but I'm wondering if I'm doing something wrong/messy here or if theres a better way to handle where I'm editing nested arrays (my attempt started in the if IsInArray section of the code)



I'd expect these two headers to edit the last array, but instead I end up creating a duplicate dictionary on the first array:



file = [
"one.array[0].dict.arrOne[0]": "1,2,3",
"one.array[0].dict.arrTwo[0]": "4,5,6"
]
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList


Outputs:



[

"one":
"array": [

"dict":
"arrOne": [
"1",
"2",
"3"
]

,

"dict":
"arrTwo": [
"4",
"5",
"6"
]


]


]


Instead of:



[

"one":
"array": [

"dict":
"arrOne": [
"1",
"2",
"3"
],
"arrTwo": [
"4",
"5",
"6"
]


]


]









share|improve this question



















  • 1





    Maybe I missed a detail here, but how does your string indicate the list index position of any selector that follows? For example in "dict.list.id": if list looks like ['id': 1, 'id': 2] how do you know which id you are referring to?

    – benvc
    Nov 12 '18 at 21:23












  • @benvc yeah thats one thing i was trying to figure out myself (maybe by putting that in the header e.g. list[0].id or by checking if the indicator is an int like list.1.id -- was hoping it could be something like the last, but haven't figured that out entirely

    – Aneuway
    Nov 12 '18 at 21:32











  • edit: added a better version of the add_branch method that (almost) handles arrays properly

    – Aneuway
    Nov 14 '18 at 15:19













2












2








2


1






Background



For some background, I'm trying to create a tool that converts worksheets into API calls using Python 3.5



For the conversion of the table cells to the schema needed for the API call, I've started down the path of using javascript like syntax for the headers used in the spreadsheet. e.g:



Worksheet Header (string)



dict.list[0].id


Python Dictionary




"dict":
"list": [
"id": "my cell value"
]



It's also possible that the header schema could have nested arrays/dicts:



one.two[0].three[0].four.five[0].six


And I also need to append to the object after it has been created as I go through each header.



What I've tried



add_branch



Based on https://stackoverflow.com/a/47276490/2903486 I am able to get nested dictionaries setup using values like one.two.three.four and I'm able to append to the existing dictionary as I go through the rows but I've been unable to add in support for arrays:



def add_branch(tree, vector, value):
key = vector[0]
tree[key] = value
if len(vector) == 1
else add_branch(tree[key] if key in tree else ,
vector[1:],
value)
return tree

file = Worksheet(filePath, sheet).readRow()
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList


My own version of add_branch



import re, json
def branch(tree, vector, value):
"""
Used to convert JS style notation (e.g dict.another.array[0].id) to a python object
Originally based on https://stackoverflow.com/a/47276490/2903486
"""

# Convert Boolean
if isinstance(value, str):
value = value.strip()

if value.lower() in ['true', 'false']:
value = True if value.lower() == "true" else False

# Convert JSON
try:
value = json.loads(value)
except:
pass

key = vector[0]
arr = re.search('[([0-9]+)]', key)
if arr:
arr = arr.group(0)
key = key.replace(arr, '')
arr = arr.replace('[', '').replace(']', '')

newArray = False
if key not in tree:
tree[key] =
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:
isInArray = False
for x in tree[key]:
if x.get(vector[1:][0], False):
isInArray = x[vector[1:][0]]

if isInArray:
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:

tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))

if len(vector) == 1 and len(tree[key]) == 1:
tree[key] = value.split(",")
else:
tree[key] = value
if len(vector) == 1
else branch(tree[key] if key in tree else ,
vector[1:],
value)
return tree


What still needs help



My branch solution works pretty well actually now after adding in some things but I'm wondering if I'm doing something wrong/messy here or if theres a better way to handle where I'm editing nested arrays (my attempt started in the if IsInArray section of the code)



I'd expect these two headers to edit the last array, but instead I end up creating a duplicate dictionary on the first array:



file = [
"one.array[0].dict.arrOne[0]": "1,2,3",
"one.array[0].dict.arrTwo[0]": "4,5,6"
]
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList


Outputs:



[

"one":
"array": [

"dict":
"arrOne": [
"1",
"2",
"3"
]

,

"dict":
"arrTwo": [
"4",
"5",
"6"
]


]


]


Instead of:



[

"one":
"array": [

"dict":
"arrOne": [
"1",
"2",
"3"
],
"arrTwo": [
"4",
"5",
"6"
]


]


]









share|improve this question
















Background



For some background, I'm trying to create a tool that converts worksheets into API calls using Python 3.5



For the conversion of the table cells to the schema needed for the API call, I've started down the path of using javascript like syntax for the headers used in the spreadsheet. e.g:



Worksheet Header (string)



dict.list[0].id


Python Dictionary




"dict":
"list": [
"id": "my cell value"
]



It's also possible that the header schema could have nested arrays/dicts:



one.two[0].three[0].four.five[0].six


And I also need to append to the object after it has been created as I go through each header.



What I've tried



add_branch



Based on https://stackoverflow.com/a/47276490/2903486 I am able to get nested dictionaries setup using values like one.two.three.four and I'm able to append to the existing dictionary as I go through the rows but I've been unable to add in support for arrays:



def add_branch(tree, vector, value):
key = vector[0]
tree[key] = value
if len(vector) == 1
else add_branch(tree[key] if key in tree else ,
vector[1:],
value)
return tree

file = Worksheet(filePath, sheet).readRow()
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList


My own version of add_branch



import re, json
def branch(tree, vector, value):
"""
Used to convert JS style notation (e.g dict.another.array[0].id) to a python object
Originally based on https://stackoverflow.com/a/47276490/2903486
"""

# Convert Boolean
if isinstance(value, str):
value = value.strip()

if value.lower() in ['true', 'false']:
value = True if value.lower() == "true" else False

# Convert JSON
try:
value = json.loads(value)
except:
pass

key = vector[0]
arr = re.search('[([0-9]+)]', key)
if arr:
arr = arr.group(0)
key = key.replace(arr, '')
arr = arr.replace('[', '').replace(']', '')

newArray = False
if key not in tree:
tree[key] =
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:
isInArray = False
for x in tree[key]:
if x.get(vector[1:][0], False):
isInArray = x[vector[1:][0]]

if isInArray:
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:

tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))

if len(vector) == 1 and len(tree[key]) == 1:
tree[key] = value.split(",")
else:
tree[key] = value
if len(vector) == 1
else branch(tree[key] if key in tree else ,
vector[1:],
value)
return tree


What still needs help



My branch solution works pretty well actually now after adding in some things but I'm wondering if I'm doing something wrong/messy here or if theres a better way to handle where I'm editing nested arrays (my attempt started in the if IsInArray section of the code)



I'd expect these two headers to edit the last array, but instead I end up creating a duplicate dictionary on the first array:



file = [
"one.array[0].dict.arrOne[0]": "1,2,3",
"one.array[0].dict.arrTwo[0]": "4,5,6"
]
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList


Outputs:



[

"one":
"array": [

"dict":
"arrOne": [
"1",
"2",
"3"
]

,

"dict":
"arrTwo": [
"4",
"5",
"6"
]


]


]


Instead of:



[

"one":
"array": [

"dict":
"arrOne": [
"1",
"2",
"3"
],
"arrTwo": [
"4",
"5",
"6"
]


]


]






python arrays python-3.x dictionary






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 15:24







Aneuway

















asked Nov 12 '18 at 21:15









AneuwayAneuway

11118




11118







  • 1





    Maybe I missed a detail here, but how does your string indicate the list index position of any selector that follows? For example in "dict.list.id": if list looks like ['id': 1, 'id': 2] how do you know which id you are referring to?

    – benvc
    Nov 12 '18 at 21:23












  • @benvc yeah thats one thing i was trying to figure out myself (maybe by putting that in the header e.g. list[0].id or by checking if the indicator is an int like list.1.id -- was hoping it could be something like the last, but haven't figured that out entirely

    – Aneuway
    Nov 12 '18 at 21:32











  • edit: added a better version of the add_branch method that (almost) handles arrays properly

    – Aneuway
    Nov 14 '18 at 15:19












  • 1





    Maybe I missed a detail here, but how does your string indicate the list index position of any selector that follows? For example in "dict.list.id": if list looks like ['id': 1, 'id': 2] how do you know which id you are referring to?

    – benvc
    Nov 12 '18 at 21:23












  • @benvc yeah thats one thing i was trying to figure out myself (maybe by putting that in the header e.g. list[0].id or by checking if the indicator is an int like list.1.id -- was hoping it could be something like the last, but haven't figured that out entirely

    – Aneuway
    Nov 12 '18 at 21:32











  • edit: added a better version of the add_branch method that (almost) handles arrays properly

    – Aneuway
    Nov 14 '18 at 15:19







1




1





Maybe I missed a detail here, but how does your string indicate the list index position of any selector that follows? For example in "dict.list.id": if list looks like ['id': 1, 'id': 2] how do you know which id you are referring to?

– benvc
Nov 12 '18 at 21:23






Maybe I missed a detail here, but how does your string indicate the list index position of any selector that follows? For example in "dict.list.id": if list looks like ['id': 1, 'id': 2] how do you know which id you are referring to?

– benvc
Nov 12 '18 at 21:23














@benvc yeah thats one thing i was trying to figure out myself (maybe by putting that in the header e.g. list[0].id or by checking if the indicator is an int like list.1.id -- was hoping it could be something like the last, but haven't figured that out entirely

– Aneuway
Nov 12 '18 at 21:32





@benvc yeah thats one thing i was trying to figure out myself (maybe by putting that in the header e.g. list[0].id or by checking if the indicator is an int like list.1.id -- was hoping it could be something like the last, but haven't figured that out entirely

– Aneuway
Nov 12 '18 at 21:32













edit: added a better version of the add_branch method that (almost) handles arrays properly

– Aneuway
Nov 14 '18 at 15:19





edit: added a better version of the add_branch method that (almost) handles arrays properly

– Aneuway
Nov 14 '18 at 15:19












1 Answer
1






active

oldest

votes


















0














So I'm not sure if there are any caveats in this solution, but this appears to work for some of the use cases i'm throwing at it:



import json, re
def build_job():

def branch(tree, vector, value):

# Originally based on https://stackoverflow.com/a/47276490/2903486

# Convert Boolean
if isinstance(value, str):
value = value.strip()

if value.lower() in ['true', 'false']:
value = True if value.lower() == "true" else False

# Convert JSON
try:
value = json.loads(value)
except:
pass

key = vector[0]
arr = re.search('[([0-9]+)]', key)

if arr:

# Get the index of the array, and remove it from the key name
arr = arr.group(0)
key = key.replace(arr,'')
arr = int(arr.replace('[','').replace(']',''))

if key not in tree:

# If we dont have an array already, turn the dict from the previous
# recursion into an array and append to it
tree[key] =
tree[key].append(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))
else:

# Check to see if we are inside of an existing array here
isInArray = False
for i in range(len(tree[key])):
if tree[key][i].get(vector[1:][0], False):
isInArray = tree[key][i][vector[1:][0]]

if isInArray:
# Respond accordingly by appending or updating the value
try:
tree[key][arr].append(value
if len(vector) == 1
else branch(tree[key] if key in tree else ,
vector[1:],
value))
except:
# Make sure we have an index to attach the requested array to
while arr >= len(tree[key]):
tree[key].append()

tree[key][arr].update(value
if len(vector) == 1
else branch(tree[key][arr] if key in tree else ,
vector[1:],
value))
else:
# Make sure we have an index to attach the requested array to
while arr >= len(tree[key]):
tree[key].append()

# update the existing array with a dict
tree[key][arr].update(value
if len(vector) == 1
else branch( if key in tree else ,
vector[1:],
value))

# Turn comma deliminated values to lists
if len(vector) == 1 and len(tree[key]) == 1:
tree[key] = value.split(",")
else:
# Add dictionaries together
tree.update(key: value
if len(vector) == 1
else branch(tree[key] if key in tree else ,
vector[1:],
value))
return tree

file = [
"one.array[0].dict.dont-worry-about-me": "some value",
"one.array[0].dict.arrOne[0]": "1,2,3",
"one.array[0].dict.arrTwo[1]": "4,5,6",
"one.array[1].x.y[0].z[0].id": "789"
]
rowList =
for row in file:
rowObj =
for colName, rowValue in row.items():
rowObj.update(branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList
print(json.dumps(build_job(), indent=4))


Result:



[

"one":
"array": [

"dict":
"dont-worry-about-me": "some value",
"arrOne": [
"1",
"2",
"3"
],
"arrTwo": [
"4",
"5",
"6"
]

,

"x":
"y": [

"z": [

"id": 789

]

]


]


]





share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53270227%2fconvert-dot-notation-string-into-nested-python-object-with-dictionaries-and-arra%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    So I'm not sure if there are any caveats in this solution, but this appears to work for some of the use cases i'm throwing at it:



    import json, re
    def build_job():

    def branch(tree, vector, value):

    # Originally based on https://stackoverflow.com/a/47276490/2903486

    # Convert Boolean
    if isinstance(value, str):
    value = value.strip()

    if value.lower() in ['true', 'false']:
    value = True if value.lower() == "true" else False

    # Convert JSON
    try:
    value = json.loads(value)
    except:
    pass

    key = vector[0]
    arr = re.search('[([0-9]+)]', key)

    if arr:

    # Get the index of the array, and remove it from the key name
    arr = arr.group(0)
    key = key.replace(arr,'')
    arr = int(arr.replace('[','').replace(']',''))

    if key not in tree:

    # If we dont have an array already, turn the dict from the previous
    # recursion into an array and append to it
    tree[key] =
    tree[key].append(value
    if len(vector) == 1
    else branch( if key in tree else ,
    vector[1:],
    value))
    else:

    # Check to see if we are inside of an existing array here
    isInArray = False
    for i in range(len(tree[key])):
    if tree[key][i].get(vector[1:][0], False):
    isInArray = tree[key][i][vector[1:][0]]

    if isInArray:
    # Respond accordingly by appending or updating the value
    try:
    tree[key][arr].append(value
    if len(vector) == 1
    else branch(tree[key] if key in tree else ,
    vector[1:],
    value))
    except:
    # Make sure we have an index to attach the requested array to
    while arr >= len(tree[key]):
    tree[key].append()

    tree[key][arr].update(value
    if len(vector) == 1
    else branch(tree[key][arr] if key in tree else ,
    vector[1:],
    value))
    else:
    # Make sure we have an index to attach the requested array to
    while arr >= len(tree[key]):
    tree[key].append()

    # update the existing array with a dict
    tree[key][arr].update(value
    if len(vector) == 1
    else branch( if key in tree else ,
    vector[1:],
    value))

    # Turn comma deliminated values to lists
    if len(vector) == 1 and len(tree[key]) == 1:
    tree[key] = value.split(",")
    else:
    # Add dictionaries together
    tree.update(key: value
    if len(vector) == 1
    else branch(tree[key] if key in tree else ,
    vector[1:],
    value))
    return tree

    file = [
    "one.array[0].dict.dont-worry-about-me": "some value",
    "one.array[0].dict.arrOne[0]": "1,2,3",
    "one.array[0].dict.arrTwo[1]": "4,5,6",
    "one.array[1].x.y[0].z[0].id": "789"
    ]
    rowList =
    for row in file:
    rowObj =
    for colName, rowValue in row.items():
    rowObj.update(branch(rowObj, colName.split("."), rowValue))
    rowList.append(rowObj)
    return rowList
    print(json.dumps(build_job(), indent=4))


    Result:



    [

    "one":
    "array": [

    "dict":
    "dont-worry-about-me": "some value",
    "arrOne": [
    "1",
    "2",
    "3"
    ],
    "arrTwo": [
    "4",
    "5",
    "6"
    ]

    ,

    "x":
    "y": [

    "z": [

    "id": 789

    ]

    ]


    ]


    ]





    share|improve this answer



























      0














      So I'm not sure if there are any caveats in this solution, but this appears to work for some of the use cases i'm throwing at it:



      import json, re
      def build_job():

      def branch(tree, vector, value):

      # Originally based on https://stackoverflow.com/a/47276490/2903486

      # Convert Boolean
      if isinstance(value, str):
      value = value.strip()

      if value.lower() in ['true', 'false']:
      value = True if value.lower() == "true" else False

      # Convert JSON
      try:
      value = json.loads(value)
      except:
      pass

      key = vector[0]
      arr = re.search('[([0-9]+)]', key)

      if arr:

      # Get the index of the array, and remove it from the key name
      arr = arr.group(0)
      key = key.replace(arr,'')
      arr = int(arr.replace('[','').replace(']',''))

      if key not in tree:

      # If we dont have an array already, turn the dict from the previous
      # recursion into an array and append to it
      tree[key] =
      tree[key].append(value
      if len(vector) == 1
      else branch( if key in tree else ,
      vector[1:],
      value))
      else:

      # Check to see if we are inside of an existing array here
      isInArray = False
      for i in range(len(tree[key])):
      if tree[key][i].get(vector[1:][0], False):
      isInArray = tree[key][i][vector[1:][0]]

      if isInArray:
      # Respond accordingly by appending or updating the value
      try:
      tree[key][arr].append(value
      if len(vector) == 1
      else branch(tree[key] if key in tree else ,
      vector[1:],
      value))
      except:
      # Make sure we have an index to attach the requested array to
      while arr >= len(tree[key]):
      tree[key].append()

      tree[key][arr].update(value
      if len(vector) == 1
      else branch(tree[key][arr] if key in tree else ,
      vector[1:],
      value))
      else:
      # Make sure we have an index to attach the requested array to
      while arr >= len(tree[key]):
      tree[key].append()

      # update the existing array with a dict
      tree[key][arr].update(value
      if len(vector) == 1
      else branch( if key in tree else ,
      vector[1:],
      value))

      # Turn comma deliminated values to lists
      if len(vector) == 1 and len(tree[key]) == 1:
      tree[key] = value.split(",")
      else:
      # Add dictionaries together
      tree.update(key: value
      if len(vector) == 1
      else branch(tree[key] if key in tree else ,
      vector[1:],
      value))
      return tree

      file = [
      "one.array[0].dict.dont-worry-about-me": "some value",
      "one.array[0].dict.arrOne[0]": "1,2,3",
      "one.array[0].dict.arrTwo[1]": "4,5,6",
      "one.array[1].x.y[0].z[0].id": "789"
      ]
      rowList =
      for row in file:
      rowObj =
      for colName, rowValue in row.items():
      rowObj.update(branch(rowObj, colName.split("."), rowValue))
      rowList.append(rowObj)
      return rowList
      print(json.dumps(build_job(), indent=4))


      Result:



      [

      "one":
      "array": [

      "dict":
      "dont-worry-about-me": "some value",
      "arrOne": [
      "1",
      "2",
      "3"
      ],
      "arrTwo": [
      "4",
      "5",
      "6"
      ]

      ,

      "x":
      "y": [

      "z": [

      "id": 789

      ]

      ]


      ]


      ]





      share|improve this answer

























        0












        0








        0







        So I'm not sure if there are any caveats in this solution, but this appears to work for some of the use cases i'm throwing at it:



        import json, re
        def build_job():

        def branch(tree, vector, value):

        # Originally based on https://stackoverflow.com/a/47276490/2903486

        # Convert Boolean
        if isinstance(value, str):
        value = value.strip()

        if value.lower() in ['true', 'false']:
        value = True if value.lower() == "true" else False

        # Convert JSON
        try:
        value = json.loads(value)
        except:
        pass

        key = vector[0]
        arr = re.search('[([0-9]+)]', key)

        if arr:

        # Get the index of the array, and remove it from the key name
        arr = arr.group(0)
        key = key.replace(arr,'')
        arr = int(arr.replace('[','').replace(']',''))

        if key not in tree:

        # If we dont have an array already, turn the dict from the previous
        # recursion into an array and append to it
        tree[key] =
        tree[key].append(value
        if len(vector) == 1
        else branch( if key in tree else ,
        vector[1:],
        value))
        else:

        # Check to see if we are inside of an existing array here
        isInArray = False
        for i in range(len(tree[key])):
        if tree[key][i].get(vector[1:][0], False):
        isInArray = tree[key][i][vector[1:][0]]

        if isInArray:
        # Respond accordingly by appending or updating the value
        try:
        tree[key][arr].append(value
        if len(vector) == 1
        else branch(tree[key] if key in tree else ,
        vector[1:],
        value))
        except:
        # Make sure we have an index to attach the requested array to
        while arr >= len(tree[key]):
        tree[key].append()

        tree[key][arr].update(value
        if len(vector) == 1
        else branch(tree[key][arr] if key in tree else ,
        vector[1:],
        value))
        else:
        # Make sure we have an index to attach the requested array to
        while arr >= len(tree[key]):
        tree[key].append()

        # update the existing array with a dict
        tree[key][arr].update(value
        if len(vector) == 1
        else branch( if key in tree else ,
        vector[1:],
        value))

        # Turn comma deliminated values to lists
        if len(vector) == 1 and len(tree[key]) == 1:
        tree[key] = value.split(",")
        else:
        # Add dictionaries together
        tree.update(key: value
        if len(vector) == 1
        else branch(tree[key] if key in tree else ,
        vector[1:],
        value))
        return tree

        file = [
        "one.array[0].dict.dont-worry-about-me": "some value",
        "one.array[0].dict.arrOne[0]": "1,2,3",
        "one.array[0].dict.arrTwo[1]": "4,5,6",
        "one.array[1].x.y[0].z[0].id": "789"
        ]
        rowList =
        for row in file:
        rowObj =
        for colName, rowValue in row.items():
        rowObj.update(branch(rowObj, colName.split("."), rowValue))
        rowList.append(rowObj)
        return rowList
        print(json.dumps(build_job(), indent=4))


        Result:



        [

        "one":
        "array": [

        "dict":
        "dont-worry-about-me": "some value",
        "arrOne": [
        "1",
        "2",
        "3"
        ],
        "arrTwo": [
        "4",
        "5",
        "6"
        ]

        ,

        "x":
        "y": [

        "z": [

        "id": 789

        ]

        ]


        ]


        ]





        share|improve this answer













        So I'm not sure if there are any caveats in this solution, but this appears to work for some of the use cases i'm throwing at it:



        import json, re
        def build_job():

        def branch(tree, vector, value):

        # Originally based on https://stackoverflow.com/a/47276490/2903486

        # Convert Boolean
        if isinstance(value, str):
        value = value.strip()

        if value.lower() in ['true', 'false']:
        value = True if value.lower() == "true" else False

        # Convert JSON
        try:
        value = json.loads(value)
        except:
        pass

        key = vector[0]
        arr = re.search('[([0-9]+)]', key)

        if arr:

        # Get the index of the array, and remove it from the key name
        arr = arr.group(0)
        key = key.replace(arr,'')
        arr = int(arr.replace('[','').replace(']',''))

        if key not in tree:

        # If we dont have an array already, turn the dict from the previous
        # recursion into an array and append to it
        tree[key] =
        tree[key].append(value
        if len(vector) == 1
        else branch( if key in tree else ,
        vector[1:],
        value))
        else:

        # Check to see if we are inside of an existing array here
        isInArray = False
        for i in range(len(tree[key])):
        if tree[key][i].get(vector[1:][0], False):
        isInArray = tree[key][i][vector[1:][0]]

        if isInArray:
        # Respond accordingly by appending or updating the value
        try:
        tree[key][arr].append(value
        if len(vector) == 1
        else branch(tree[key] if key in tree else ,
        vector[1:],
        value))
        except:
        # Make sure we have an index to attach the requested array to
        while arr >= len(tree[key]):
        tree[key].append()

        tree[key][arr].update(value
        if len(vector) == 1
        else branch(tree[key][arr] if key in tree else ,
        vector[1:],
        value))
        else:
        # Make sure we have an index to attach the requested array to
        while arr >= len(tree[key]):
        tree[key].append()

        # update the existing array with a dict
        tree[key][arr].update(value
        if len(vector) == 1
        else branch( if key in tree else ,
        vector[1:],
        value))

        # Turn comma deliminated values to lists
        if len(vector) == 1 and len(tree[key]) == 1:
        tree[key] = value.split(",")
        else:
        # Add dictionaries together
        tree.update(key: value
        if len(vector) == 1
        else branch(tree[key] if key in tree else ,
        vector[1:],
        value))
        return tree

        file = [
        "one.array[0].dict.dont-worry-about-me": "some value",
        "one.array[0].dict.arrOne[0]": "1,2,3",
        "one.array[0].dict.arrTwo[1]": "4,5,6",
        "one.array[1].x.y[0].z[0].id": "789"
        ]
        rowList =
        for row in file:
        rowObj =
        for colName, rowValue in row.items():
        rowObj.update(branch(rowObj, colName.split("."), rowValue))
        rowList.append(rowObj)
        return rowList
        print(json.dumps(build_job(), indent=4))


        Result:



        [

        "one":
        "array": [

        "dict":
        "dont-worry-about-me": "some value",
        "arrOne": [
        "1",
        "2",
        "3"
        ],
        "arrTwo": [
        "4",
        "5",
        "6"
        ]

        ,

        "x":
        "y": [

        "z": [

        "id": 789

        ]

        ]


        ]


        ]






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 14 '18 at 19:02









        AneuwayAneuway

        11118




        11118



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53270227%2fconvert-dot-notation-string-into-nested-python-object-with-dictionaries-and-arra%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Use pre created SQLite database for Android project in kotlin

            Darth Vader #20

            Ondo