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.
Answer from steveha on Stack OverflowI 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}
Looping through JSON in python - Stack Overflow
python - Read a JSON File in a FOR loop - Stack Overflow
Python: Loop through JSON File - Stack Overflow
Loop through JSON data in Python - Stack Overflow
Videos
You should add second loop and iterate matches:
for rounds in js['rounds']:
for matches in rounds['matches']:
print(matches['team1']['name'])
you are taking first item in the list of matches, just loop through the list again like,
for matchday in js['rounds'] :
match_day = matchday['matches']
for each_match in match_day:
print(each_match['team1']['name'])
json_formatted_str is a string, and iterating through a string will yield the individual characters. You probably want something like for line in json_formatted_str.split("\n")
json_formatted_str.splitlines() will return a list of all of the lines.
In your case:
for line in json_formatted_str.splitlines():
print(line)
This is probably the easiest solution.
The solution of diek is the one that worked for me, edited my post because of this. The better code is:
import requests
import json
response = requests.get("")
data =response.text
parsed=json.loads(data)
for product in parsed['products']:
print(product['id'])
The output will look as follow:
66057248
66057245
66057242
66057239
66057236
66057233
66057230
66057227
66057224
You can do:
for product in parsed:
for index in parsed[product]:
for element in parsed[product][index]:
print(element.id)
print(element.createdAt)
# ...
In Simon's answer the id value in the loop would actually be 'id', 'createdAt' and etc. To print only ids as it suggests you need to assert if the key is equals to 'id', what makes the loop useless.
Note: It is not suggested to use id as variable name. It is a reserved word, in this case you can add the underscore getting id_ instead.
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"
}
]
},If you want to produce valid JSON file you need to write all values at once, not one value at a time (which will produce ndjson or JSON lines)
So, for a valid JSON
values = [{"first_name": "John", "last_name": "Smith", "food": "corn"},
{"first_name": "Jane", "last_name": "Doe", "food": "soup"}]
import json
with open('some_file.json', 'w') as f:
json.dump(values, f, indent=4)
some_file.json
[
{
"first_name": "John",
"last_name": "Smith",
"food": "corn"
},
{
"first_name": "Jane",
"last_name": "Doe",
"food": "soup"
}
]
if you really need ndjson - you can use ndjson package (need install via pip from PyPi).
import ndjson
with open('some_file2.ndjson', 'w') as f:
ndjson.dump(values, f)
some_file2.ndjson
{"first_name": "John", "last_name": "Smith", "food": "corn"}
{"first_name": "Jane", "last_name": "Doe", "food": "soup"}
Alternative to ndjson package is jsonlines package
You can newline after each
f.write(json.dumps(value, sort_keys=True, indent=0))
like this - f.write('\n')
You have a JSON Lines format text file. You need to parse your file line by line:
import json
data = []
with open('file') as f:
for line in f:
data.append(json.loads(line))
Each line contains valid JSON, but as a whole, it is not a valid JSON value as there is no top-level list or object definition.
Note that because the file contains JSON per line, you are saved the headaches of trying to parse it all in one go or to figure out a streaming JSON parser. You can now opt to process each line separately before moving on to the next, saving memory in the process. You probably don't want to append each result to one list and then process everything if your file is really big.
If you have a file containing individual JSON objects with delimiters in-between, use How do I use the 'json' module to read in one JSON object at a time? to parse out individual objects using a buffered method.
In case you are using pandas and you will be interested in loading the json file as a dataframe, you can use:
import pandas as pd
df = pd.read_json('file.json', lines=True)
And to convert it into a json array, you can use:
df.to_json('new_file.json')
Your question is a little unclear. If you're generating hostDict in a loop:
with open('data.txt', 'a') as outfile:
for hostDict in ....:
json.dump(hostDict, outfile)
outfile.write('\n')
If you mean you want each variable within hostDict to be on a new line:
with open('data.txt', 'a') as outfile:
json.dump(hostDict, outfile, indent=2)
When the indent keyword argument is set it automatically adds newlines.
To avoid confusion, paraphrasing both question and answer. I am assuming that user who posted this question wanted to save dictionary type object in JSON file format but when the user used json.dump, this method dumped all its content in one line. Instead, he wanted to record each dictionary entry on a new line. To achieve this use:
with g as outfile:
json.dump(hostDict, outfile,indent=2)
Using indent = 2 helped me to dump each dictionary entry on a new line. Thank you @agf. Rewriting this answer to avoid confusion.
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)
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)
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)