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)
Answer from alecxe on Stack OverflowThe 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)
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)
You need to maintain two lists for scores and titles and append all the data to those lists, instead of printing, and then zip those lists along with list comprehension to get the desired output as :
import json
scores, titles = [], []
for line in games_html.findAll('div', class_="product_score"):
scores.append(line.getText(strip=True))
for line in games_html.findAll('a'):
titles.append(line.getText(strip=True))
score_titles = [{"Title": t, "Score": s} for t, s in zip(titles, scores)]
print score_titles
# Printing in JSON format
print json.dumps(score_titles)
As ZdaR's post illustrates, to create a json, you need to build the corresponding Python data structure (lists for json arrays, dictionaries for json objects) and serialize it at the end. So the question is almost the same as how to create a list in a loop, because after creating the list, what remains is serialization which is as simple as json.loads(data).
The task in the OP can be done in two loops:
data = [{'Title': line.getText(strip=True)} for line in games_html.findAll('a')]
for i, line in enumerate(games_html.findAll('div', class_="product_score")):
data[i]['Score'] = line.getText(strip=True)
# serialize to json array
j = json.dumps(data)
# or write to a file
with open('data.json', 'w') as f:
json.dump(data, f)
How to create JSON data in a loop in Python? - Stack Overflow
Using Python to loop through JSON dictionary that re-uses the same key?
Create JSON in for loop in Python - Stack Overflow
python - Create multiple json objects by using for loop - Stack Overflow
I'm trying to restructure JSON output from a API to the specific format that Ansible wants for it's invetory file. To do this I thought I would loop through the JSON and grab the variables I need and then feed that into the proper structure. However, I noticed my API JSON is using the same $ key for multiple variables. How can I properly reference and differentiate between the variables? Here is an example:
"model-responses": {
"model": [
{
"@mh": "0x11e013",
"attribute": [
{
"@id": "0x1006e",
"$": "switch1"
},
{
"@id": "0x23000e",
"$": "Raritan Computer, Inc.DV"
},
{
"@id": "0x12d7f",
"$": "10.10.10.1"
},
{
"@id": "0x10052",
"$": "PX2 030610"
}
]
},
{
"@mh": "0x115014",
"attribute": [
{
"@id": "0x1006e",
"$": "switch2"
},
{
"@id": "0x23000e",
"$": "DCS-7010T-48"
},
{
"@id": "0x12d7f",
"$": "10.10.10.2"
},
{
"@id": "0x10052",
"$": "Arista Networks EOS version 4.22.3M-INT running on an Arista Networks DCS-7010T-48"
}
]
},That's because you used string. How about that:
for i in range(10):
json_Daten2[i] = {"ID": i}
you dont need to do this man, python dumps json naturaly:
from json import dump,dumps
MY_DATA = [
{'id':112,'tempeture':2.23},
{'id':112,'tempeture':2.23}
]
#if you want in string mode
result = dumps(MY_DATA,ensure_ascii=False,indent=4)
print(result)
#if you want in file
with open('teste.json','w') as arq:
dump(MY_DATA,arq)
I suggest several possible solutions.
One solution is to write custom code to slurp in the input file. I would suggest putting a special line before each JSON object in the file, such as: ###
Then you could write code like this:
import json
def json_get_objects(f):
temp = ''
line = next(f) # pull first line
assert line == SPECIAL_LINE
for line in f:
if line != SPECIAL_LINE:
temp += line
else:
# found special marker, temp now contains a complete JSON object
j = json.loads(temp)
yield j
temp = ''
# after loop done, yield up last JSON object
if temp:
j = json.loads(temp)
yield j
with open("specs_data.txt", "r") as f:
for j in json_get_objects(f):
pass # do something with JSON object j
Two notes on this. First, I am simply appending to a string over and over; this used to be a very slow way to do this in Python, so if you are using a very old version of Python, don't do it this way unless your JSON objects are very small. Second, I wrote code to split the input and yield up JSON objects one at a time, but you could also use a guaranteed-unique string, slurp in all the data with a single call to f.read() and then split on your guaranteed-unique string using the str.split() method function.
Another solution would be to write the whole file as a valid JSON list of valid JSON objects. Write the file like this:
{"mylist":[
# first JSON object, followed by a comma
# second JSON object, followed by a comma
# third JSON object
]}
This would require your file appending code to open the file with writing permission, and seek to the last ] in the file before writing a comma plus newline, then the new JSON object on the end, and then finally writing ]} to close out the file. If you do it this way, you can use json.loads() to slurp the whole thing in and have a list of JSON objects.
Finally, I suggest that maybe you should just use a database. Use SQLite or something and just throw the JSON strings in to a table. If you choose this, I suggest using an ORM to make your life simple, rather than writing SQL commands by hand.
Personally, I favor the first suggestion: write in a special line like ###, then have custom code to split the input on those marks and then get the JSON objects.
EDIT: Okay, the first suggestion was sort of assuming that the JSON was formatted for human readability, with a bunch of short lines:
{
"foo": 0,
"bar": 1,
"baz": 2
}
But it's all run together as one big long line:
{"foo":0,"bar":1,"baz":2}
Here are three ways to fix this.
0) write a newline before the ### and after it, like so:
###
{"foo":0,"bar":1,"baz":2}
###
{"foo":0,"bar":1,"baz":2}
Then each input line will alternately be ### or a complete JSON object.
1) As long as SPECIAL_LINE is completely unique (never appears inside a string in the JSON) you can do this:
with open("specs_data.txt", "r") as f:
temp = f.read() # read entire file contents
lst = temp.split(SPECIAL_LINE)
json_objects = [json.loads(x) for x in lst]
for j in json_objects:
pass # do something with JSON object j
The .split() method function can split up the temp string into JSON objects for you.
2) If you are certain that each JSON object will never have a newline character inside it, you could simply write JSON objects to the file, one after another, putting a newline after each; then assume that each line is a JSON object:
import json
def json_get_objects(f):
for line in f:
if line.strip():
yield json.loads(line)
with open("specs_data.txt", "r") as f:
for j in json_get_objects(f):
pass # do something with JSON object j
I like the simplicity of option (2), but I like the reliability of option (0). If a newline ever got written in as part of a JSON object, option (0) would still work, but option (2) would error.
Again, you can also simply use an actual database (SQLite) with an ORM and let the database worry about the details.
Good luck.
Append json data to a dict on every loop.
In the end dump this dict as a json and write it to a file.
For getting you an idea for appending data to dict:
>>> d1 = {'suku':12}
>>> t1 = {'suku1':212}
>>> d1.update(t1)
>>> d1
{'suku1': 212, 'suku': 12}
I believe you probably meant:
from __future__ import print_function
for song in json_object:
# now song is a dictionary
for attribute, value in song.items():
print(attribute, value) # example usage
NB: You could use song.iteritems instead of song.items if in Python 2.
Your loading of the JSON data is a little fragile. Instead of:
json_raw= raw.readlines()
json_object = json.loads(json_raw[0])
you should really just do:
json_object = json.load(raw)
You shouldn't think of what you get as a "JSON object". What you have is a list. The list contains two dicts. The dicts contain various key/value pairs, all strings. When you do json_object[0], you're asking for the first dict in the list. When you iterate over that, with for song in json_object[0]:, you iterate over the keys of the dict. Because that's what you get when you iterate over the dict. If you want to access the value associated with the key in that dict, you would use, for example, json_object[0][song].
None of this is specific to JSON. It's just basic Python types, with their basic operations as covered in any tutorial.