Generating a json in a loop in python

Question:

I have some difficulties generating a specific JSON object in python.

I need it to be in this format:

[
   {"id":0 , "attributeName_1":"value" , "attributeName_2":"value" , .... },
   {"id":1 , "attributeName_2":"value" , "attributeName_3":"value" , .... },
   .
   .
   .
]

I’m getting the ids, attributeNames and values from 2 objects. I’m trying to generate the json like this:

data=[]
for feature in features_selected:
    data.append({"id":feature.pk})
    for attribute in attributes_selected:
        if attribute.feature == feature:
            data.append({attribute.attribute.name : attribute.value})
    jsonData=json.dumps(data)

but I got this result which is not exactly what I need:

[
   {"id":0} , {"attributeName_1":"value"} , {"attributeName_2":"value"} ,
   {"id":1} , {"attributeName_2":"value"} , {"attributeName_3":"value"} , .... },
   .
   .
   .
]
Asked By: Below the Radar

||

Answers:

The problem is that you are appending to data multiple times in the loop: first {"id":feature.pk}, then {attribute.attribute.name : attribute.value} in the inner loop.

Instead, you need to define a dictionary inside the loop, fill it with id item and attributes and only then append:

data=[]
for feature in features_selected:
    item = {"id": feature.pk}
    for attribute in attributes_selected:
        if attribute.feature == feature:
            item[attribute.attribute.name] = attribute.value
    data.append(item)

jsonData=json.dumps(data)
Answered By: alecxe

For those who came here looking for a way to create an arbitrary json in a loop, the question is akin to creating a Python list / dictionary in a loop because the canonical way to build a json in Python is to build the corresponding Python data structure (list -> json array, dictionary -> json object) and serialize it using json.dump (to store it in a json file) or json.dumps (to create a json string in memory).

The case in the OP may be one case where a comprehension makes the loop more intuitive and less error-prone. The nested structure in the OP can be written as a dict comprehension nested inside a list comprehension. The idea is to build a dictionary in each outer iteration using an inner iteration. Two dictionaries can be merged as well, which is put to use since an 'id' key is needed in each dict. A similar example is as follows:

data = [{'id': i+10, **{j: j // 2 for j in range(i, i+60) if j % 30 == 0}} for i in range(2)]

# convert to a json string
json_string = json.dumps(data)
# '[{"id": 10, "0": 0, "30": 15}, {"id": 11, "30": 15, "60": 30}]'

# or
# write to a json file
with open('myjson.json', 'w') as f:
    json.dump(data, f)
Answered By: cottontail
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.