0

I have a nested json that looks like this:

[
    {
        'Name':'Anders', 
        'Type':'Hunter', 
        'Race':'Cyborg', 
    },
    {
        'Name':'Karin', 
        'Type':'Titan', 
        'Race':'Human', 
    },
    {
        'Name':'Jenny', 
        'Type':'Warlock', 
        'Race':'Marsian', 
    },
]

And I have a string that looks like this:

['1', 'Ham', 'Spam', 'Bacon', '1', 'Ham', 'Cucumber', 'Tomato', '1', 'Wood', 'Potato', 'Herring']

I want to insert the string into the json with a name for the value. Each four in the string is for each person in the json.

Final result should look like this:

    [
    {
        'Name':'Anders', 
        'Type':'Hunter', 
        'Race':'Cyborg',
        'string1':'1',
        'Food_1':'Ham',
        'Food_2':'Spam',
        'Food_3':'Bacon',
    },
    {
        'Name':'Karin', 
        'Type':'Titan', 
        'Race':'Human',
        'string1':'1',
        'Food_1':'Ham',
        'Food_2':'Cucumber',
        'Food_3':'Tomato',
    },
    {
        'Name':'Jenny', 
        'Type':'Warlock', 
        'Race':'Marsian',
        'string1':'1',
        'Food_1':'Wood',
        'Food_2':'Potato',
        'Food_3':'Herring',     
    },
]

I have tryied with some iterations, but fails all the time :/

Hope you can help me!

sumpen
  • 503
  • 6
  • 19
  • 1
    You don't modify JSON directly; you decode it, update the resulting data structure, then re-encode the modified data structure. – chepner Aug 11 '17 at 11:50

3 Answers3

1

I'm assuming your data structures are python dicts and lists, and not strings containing json-text.

First, turn your flat list of things to insert into a list of chunks of 4 items each. You can read up on some other ways of doing that here.

new_things = ['1', 'Ham', 'Spam', 'Bacon', '1', 'Ham', 'Cucumber', 'Tomato', '1', 'Wood', 'Potato', 'Herring']
chunks = [new_things[i:i+4] for i in range(0, len(new_things), 4)]

Resulting in:

[['1', 'Ham', 'Spam', 'Bacon'], ['1', 'Ham', 'Cucumber', 'Tomato'], ['1', 'Wood', 'Potato', 'Herring']]

Then, iterate over the two collections simultaneously. You can use zip for this:

for entry, new_stuff in zip(existing_data, chunks):
    entry["string1"] = new_stuff[0]
    entry["Food_1"] = new_stuff[1]
    entry["Food_2"] = new_stuff[2]
    entry["Food_3"] = new_stuff[3]

After that, your collection should look like expected.

Felk
  • 7,720
  • 2
  • 35
  • 65
0

Alternative to answer 1:

json_list = [
    {
        'Name':'Anders', 
        'Type':'Hunter', 
        'Race':'Cyborg', 
    },
    {
        'Name':'Karin', 
        'Type':'Titan', 
        'Race':'Human', 
    },
    {
        'Name':'Jenny', 
        'Type':'Warlock', 
        'Race':'Marsian', 
    },]
foods = ['1', 'Ham', 'Spam', 'Bacon', '1', 'Ham', 'Cucumber', 'Tomato', '1', 'Wood', 'Potato', 'Herring']
for _ in json_list:
    _.update({'string1': foods[0], 'food_1': foods[1], 'food_2': foods[2], 'food_3': foods[3]})
    foods = foods[4:]
json_list

Results in

[{'Race': 'Cyborg', 'food_3': 'Bacon', 'string1': '1', 'food_2': 'Spam', 'Name': 'Anders', 'Type': 'Hunter', 'food_1': 'Ham'}, {'Race': 'Human', 'food_3': 'Tomato', 'string1': '1', 'food_2': 'Cucumber', 'Name': 'Karin', 'Type': 'Titan', 'food_1': 'Ham'}, {'Race': 'Marsian', 'food_3': 'Herring', 'string1': '1', 'food_2': 'Potato', 'Name': 'Jenny', 'Type': 'Warlock', 'food_1': 'Wood'}]
BoboDarph
  • 2,751
  • 1
  • 10
  • 15
0

A compact way to do this is to use the iter and zip functions to break the new data up into chunks.

import json

data = [
    {
        'Name':'Anders', 
        'Type':'Hunter', 
        'Race':'Cyborg', 
    },
    {
        'Name':'Karin', 
        'Type':'Titan', 
        'Race':'Human', 
    },
    {
        'Name':'Jenny', 
        'Type':'Warlock', 
        'Race':'Marsian', 
    },
]

keys = ['string1', 'Food_1', 'Food_2', 'Food_3']
new_data = [
    '1', 'Ham', 'Spam', 'Bacon', 
    '1', 'Ham', 'Cucumber', 'Tomato', 
    '1', 'Wood', 'Potato', 'Herring',
]

# Create an iterator that yields chunks of length 4 from new_data
chunks = zip(*[iter(new_data)] * 4)

# Update the dicts in data with the new data
for d, t in zip(data, chunks):
    d.update(zip(keys, t))

# Convert to JSON
json_data = json.dumps(data, indent=4)
print(json_data)

output

[
    {
        "Name": "Anders",
        "Type": "Hunter",
        "Race": "Cyborg",
        "string1": "1",
        "Food_1": "Ham",
        "Food_2": "Spam",
        "Food_3": "Bacon"
    },
    {
        "Name": "Karin",
        "Type": "Titan",
        "Race": "Human",
        "string1": "1",
        "Food_1": "Ham",
        "Food_2": "Cucumber",
        "Food_3": "Tomato"
    },
    {
        "Name": "Jenny",
        "Type": "Warlock",
        "Race": "Marsian",
        "string1": "1",
        "Food_1": "Wood",
        "Food_2": "Potato",
        "Food_3": "Herring"
    }
]

We could also put the "chunkifying" step into the main for loop:

for d, t in zip(data, zip(*[iter(new_data)] * 4)):
    d.update(zip(keys, t))

but I think the previous version is a little more readable.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182