I have a line like this and I need to convert it to json format
{from:[3,4],to:[7,4],color:2},{from:[3,6],to:[10,6],color:3},{from:[5,8],to:[9,8],color:5},{from:[5,11],to:[10,11],color:6},{from:[1,0],to:[1,11],color:0},{from:[10,1],to:[10,6],color:4},{from:[3,0],to:[8,0],color: 1}
Applying this code, I will transform it, but not completely, as I need
def select(value):
ll = value.split(',{')
ll = [element.replace("{", '') for element in ll]
ll = [element.replace("}", '') for element in ll]
js = {str(i):letter for i,letter in enumerate(ll)}
js = json.dumps(js)
return js
total["data_words_selection"] = total["data_words_selection"].map(lambda x: str(x).lstrip("['").rstrip("']")).astype(str)
total['data_words_selection'] = total['data_words_selection'].apply(select)
I receive it like this:
{
"0": "from:[3,4],to:[7,4],color:2",
"1": "from:[3,6],to:[10,6],color:3",
"2": "from:[5,8],to:[9,8],color:5",
"3": "from:[5,11],to:[10,11],color:6",
"4": "from:[1,0],to:[1,11],color:0",
"5": "from:[10,1],to:[10,6],color:4",
"6": "from:[3,0],to:[8,0],color:1"
}
I get valid json. Please tell me how can I convert this string to this format:
{
"0":
"from":
"0": "3"
"1": "4"
"to":
"0": "7"
"1": "4"
"color": "2"
"1":
"from":
"0": "3"
"1": "6"
"to":
"0": "10"
"1": "5"
"color": "3"
}
The result, which I would like to see, was written by hand, sorry for the mistakes. please tell me
This is an example of what it should look like. I hope you understand what I want
As other guys said. It is not perfectly clear what you want to do. But maybe this code can help you:
import json
import re
input_ = "{from:[3,4],to:[7,4],color:2},{from:[3,6],to:[10,6],color:3},{from:[5,8],to:[9,8],color:5},{from:[5,11],to:[10,11],color:6},{from:[1,0],to:[1,11],color:0},{from:[10,1],to:[10,6],color:4},{from:[3,0],to:[8,0],color:1}"
def parse_json(input_):
arr = input_.split("},")
arr = [x+"}" for x in arr]
arr[-1] = arr[-1][:-1]
return json.dumps({str(i):add_quotation_marks(x) for i, x in enumerate(arr)})
def add_quotation_marks(input_):
words = re.findall(r'(\w+:)', input_)
for word in words:
input_ = input_.replace(word[:-1], f'"{word[:-1]}"')
return json.loads(input_)
print(parse_json(input_))
List stay as list, but it could be transformed into dict.
Related
I have a large script that parses js with a dataframe entry, but to shorten the question, I put what I need in a separate variable.
My variable contains the following value
value = "{from:[3,4],to:[7,4],color:2},{from:[3,6],to:[10,6],color:3}"
I apply the following script and get data like this
value = "{from:[3,4],to:[7,4],color:2},{from:[3,6],to:[10,6],color:3}"
def parse_json(value):
arr = value.split("},")
arr = [x+"}" for x in arr]
arr[-1] = arr[-1][:-1]
return json.dumps({str(i):add_quotation_marks(x) for i, x in enumerate(arr)})
def add_quotation_marks(value):
words = re.findall(r'(\w+:)', value)
for word in words:
value = value.replace(word[:-1], f'"{word[:-1]}"')
return json.loads(value)
print(parse_json(value))
{"0": {"from": [3, 4], "to": [7, 4], "color": 2}, "1": {"from": [3, 6], "to": [10, 6], "color": 3}}
The script executes correctly, but I need to get a slightly different result.
This is what the result I want to get looks like:
{
"0": {
"from": {
"0": "3",
"1": "4"
},
"to": {
"0": "7",
"1": "4"
},
"color": "2"
},
"1": {
"from": {
"0": "3",
"1": "6"
},
"to": {
"0": "10",
"1": "6"
},
"color": "3"
}
}
This is valid json and valid yaml. Please tell me how can I do this
I'd suggest a regex approach in this case:
res = []
# iterates over each "{from:...,to:...,color:...}" group separately
for obj in re.findall(r'\{([^}]+)}', value):
item = {}
# iterates over each "...:..." key-value separately
for k, v in re.findall(r'(\w+):(\[[^]]+]|\d+)', obj):
if v.startswith('['):
v = v.strip('[]').split(',')
item[k] = v
res.append(item)
This produces this output in res:
[{'from': ['3', '4'], 'to': ['7', '4'], 'color': '2'}, {'from': ['3', '6'], 'to': ['10', '6'], 'color': '3'}]
Since your values can contain commas, trying to split on commas or other markers is fairly tricky, and using these regexes to match your desired values instead is more stable.
Here's the code that converts the the value to your desired output.
import json5 # pip install json5
value = "{from:[3,4],to:[7,4],color:2},{from:[3,6],to:[10,6],color:3}"
def convert(str_value):
str_value = f"[{str_value}]" # added [] to make it a valid json
parsed_value = json5.loads(str_value) # convert to python object
output = {} # create empty dict
# Loop through the list of dicts. For each item, create a new dict
# with the index as the key and the value as the value. If the value
# is a list, convert it to a dict with the index as the key and the
# value as the value. If the value is not a list, just add it to the dict.
for i, d in enumerate(parsed_value):
output[i] = {}
for k, v in d.items():
output[i][k] = {j: v[j] for j in range(len(v))} if isinstance(v, list) else v
return output
print(json5.dumps(convert(value)))
Output
{
"0": {
"from": {
"1": 4
},
"to": {
"0": 7,
"1": 4
},
"color": 2
},
"1": {
"from": {
"0": 3,
"1": 6
},
"to": {
"0": 10,
"1": 6
},
"color": 3
}
}
json5 package allows you to convert a javascrip object to a python dictionary so you dont have to do split("},{").
Then added [ and ] to make the string a valid json.
Then load the string using json5.loads()
Now you can loop through the dictionary and convert it to desired output format.
I'm writing some Python code (data extraction from a ConLL-U format file) and I want my data to be stored in a .json file. I'd like to achieve an output's format like the following (x are keys, y are values):
{
"lemma": {"x": "y","x": [{"x":"y"}], "x": "y", "x": [{"x":"y"}], "x": "" },
"lemma1":{"x": "y", "x": [{"x":"y"}], "x": "y", "x": [{"x":"y"}], "x": "y" }...
}
Last section of my code (it's probably quite inefficient, but now I'm just intersted in formatting the json output):
token_info= {}
...
sentences = []
tokens = []
idn_dep_dict = {}
for line in lines:
if line == '\n':
sentences.append(tokens)
tokens = []
else:
fields = line.strip().split('\t')
if len(fields) >= 1:
if fields[0].isdigit():
idn = fields[0]
lemma = fields[1]
upos = fields[3]
xpos = fields[4]
feats = fields[5]
dep = fields[6]
pos_pair = (upos,xpos)
tokens.append((idn, lemma, pos_pair,feats,dep))
idn_dep_dict[idn]=[dep]
else:
continue
for sentence in sentences:
dependencies_dict = {} #dictionary for the dependencies of the current sentence
for token in sentence:
idn, lemma, pos_pair, feats, dep = token
if dep == '0':
dependencies_dict[idn] = 'root'
if dep in idn_dep_dict:
for head_token in sentence:
if head_token[0] == dep:
dependencies_dict[idn] = head_token[2]
# Create a dictionary for the current token's information
current_token = {'x1': [upos], 'x2': [{'0': pos_pair}],'x3': [{'0': dependencies_dict[idn]}],'x4': feats}
token_info[lemma] = current_token
# Write the JSON data to a file
with open('token_info.json', 'w', encoding='utf-8') as f:
json.dump(token_info, f, ensure_ascii=False, indent = 2, separators=(',', ': '))
The current code generates a newline after each [,] or {,} or comma in the json file. I'd like to have each lemma = {corrisponding dictionary} on each line. Is it possible? Thank you all in advance
Serialize one level of the dictionary structure manually like this.
import json
token_info = json.loads('''
{
"lemma": {"x": "y","x2": [{"x":"y"}], "x3": "y", "x4": [{"x":"y"}], "x5": "" },
"lemma1":{"x": "y", "x2": [{"x":"y"}], "x3": "y", "x4": [{"x":"y"}], "x5": "y" }
}
''')
lines = []
for k, v in token_info.items():
ks = json.dumps(k, ensure_ascii=False)
vs = json.dumps(v, ensure_ascii=False, separators=(',', ': '))
lines.append(ks + ': ' + vs)
src = '{\n ' + (',\n '.join(lines)) + '\n}'
print(src)
This will output the following.
{
"lemma": {"x": "y","x2": [{"x": "y"}],"x3": "y","x4": [{"x": "y"}],"x5": ""},
"lemma1": {"x": "y","x2": [{"x": "y"}],"x3": "y","x4": [{"x": "y"}],"x5": "y"}
}
This question already has an answer here:
How to create a counter that counts unrighteous inputs
(1 answer)
Closed 2 months ago.
I need to put this code in a loop so that you can choose whichever number first and go back to the start after whichever one you choose, but everything I've tried hasn't worked and need help.
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
option = int(input("Enter an option: "))
if option == 1:
people = input("Who are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"]
[item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
option = int(input("\nEnter an option: "))
if option == 2:
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
answer = input("Do you want to complete their shopping list (Y/N)? ")
if answer.upper() == "Y":
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
option = int(input("\nEnter an option: "))
if option == 3:
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
option = int(input("\nEnter an option: "))
if option == 4:
print("Thank You For Shopping With Us!")
I've tried putting in different versions of loop, but it always either results in the program ignoring it and not going back to the start, or breaking when I choose something else then 1 at the start.
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
With the same list above, After adding in my information to the set example given, I would get the error below.
error with pic: https://i.stack.imgur.com/BrqBB.png
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
while True:
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
It now looks exactly like this, and it still gives back a syntax error on the first elif statement. I don't understand what the problem is if it's properly indented and should follow the correct rules to use it.
edited with error: https://i.stack.imgur.com/rTW6k.png
The syntax error is finally gone, but now lies the problem where the code just repeats itself on the menu screen without going anywhere, like this:
repeating: https://i.stack.imgur.com/YNPdF.png
I would do something like this:
while True:
print(<instructions>)
option = input("Enter an option: ")
if option == "1":
do stuff...
elif option == "2":
do number two stuff..
elif option == "3":
do that third stuff..
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
This will keep the menu in a loop and if option 4 is selected, it will break from the loop and continue on.
The issue now is with your indentation. You must indent your code properly for python to be able to understand what you want it to do, for instance:
x= "3"
if x == "2":
print("hello world")
print("outside the indent")
you console output would be:
>>outside the indent
but if your code looks like this:
x= "3"
if x == "2":
print("hello world")
print("outside the indent")
you would get no output from the console, everything is within the "if" code block. Indentation is crucial for python to exhibit the expected behavior. you need to make sure that all your code for each condition is indented properly inside the if blocks, like the example I gave above. Also, if you want this in a loop, you need to put it in a loop with the while True: statement, and indent everything inside it.
Your final result should look something like this:
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
while True:
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
Also, please review this link as it is crucial you understand how to properly indent your code when writing python.
https://www.geeksforgeeks.org/indentation-in-python/
I am trying to download a Json file from an API and convert it into a csv file, but the script throws the below error while parsing the json file.
For every 100 records json file closes the "]" and starts another "[". This format is not being accepted as json format. could you please suggest me how i can parse the "]" and "[" which appears every 100 records in an efficient way.The code works fine for less than 100 records without the [] brackets.
Error message:
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data
Json file format:
**[**
{
"A": "5",
"B": "811",
"C": [
{ "C1": 1,
"C2": "sa",
"C3": 3
}
],
"D": "HH",
"E": 0,
"F": 6
},
{
"A": "5",
"B": "811",
"C": [
{ "C1": 1,
"C2": "fa",
"C3": 3
}
],
"D": "HH",
"E": 0,
"F": 6
}
**]**
**[**
{
"A": "5",
"B": "811",
"C": [
{ "C1": 1,
"C2": "da",
"C3": 3
}
],
"D": "HH",
"E": 0,
"F": 6
}
**]**
Code:
import json
import pandas as pd
from flatten_json import flatten
def json2excel():
file_path = r"<local file path>"
json_list = json.load(open(file_path + '.json', 'r', encoding='utf-8', errors='ignore'))
key_list = ['A', 'B']
json_list = [{k: d[k] for k in key_list} for d in json_list]
# Flatten and convert to a data frame
json_list_flattened = (flatten(d, '.') for d in json_list)
df = pd.DataFrame(json_list_flattened)
# Export to CSV in the same directory with the original file name
export_csv = df.to_csv(file_path + r'.csv', sep=',', encoding='utf-8', index=None, header=True)
def main():
json2excel()
I would recommend parsing your data that you receive from your API first. This pre-processed data can be fed to a JSON parser later.
I came up with a simple python code that's just a small tweak to the solution of parenthesis matching problem. Here's my working code that you might use for pre-processing your data.
def build_json_items(custom_json):
open_tup = tuple('({[')
close_tup = tuple(')}]')
map = dict(zip(open_tup, close_tup))
queue = []
json_items = []
temp = ""
for i in custom_json:
if i in open_tup:
queue.append(map[i])
elif i in close_tup:
if not queue or i != queue.pop():
return "Unbalanced"
if len(queue) == 0:
# We have reached to a point where everything so far is balanced.
# This is the point where we can separate out the expression
temp = temp + str(i)
json_items.append(temp)
temp = "" # Re-initialize
else:
temp = temp + str(i)
if not queue:
# Provided string is balanced
return True, json_items
else:
return False, json_items
This build_json_items function will take your custom JSON payload and will parse individual valid JSON items based on the information that you provided in your question. Here's an example of how you can trigger this function. You can use the following.
input_data = "[{\"A\":\"5\",\"B\":\"811\",\"C\":[{\"C1\":1,\"C2\":\"sa\",\"C3\":3}],\"D\":\"HH\",\"E\":0,\"F\":6},{\"A\":\"5\",\"B\":\"811\",\"C\":[{\"C1\":1,\"C2\":\"fa\",\"C3\":3}],\"D\":\"HH\",\"E\":0,\"F\":6}][{\"A\":\"5\",\"B\":\"811\",\"C\":[{\"C1\":1,\"C2\":\"da\",\"C3\":3}],\"D\":\"HH\",\"E\":0,\"F\":6}]"
is_balanced, json_items = build_json_items(input_data)
print(f"Available JSON items: {len(json_items)}")
print("JSON items are the following")
for i in json_items:
print(i)
Here's the output of the print statements.
Available JSON items: 2
JSON items are the following
[{"A":"5","B":"811","C":[{"C1":1,"C2":"sa","C3":3}],"D":"HH","E":0,"F":6},{"A":"5","B":"811","C":[{"C1":1,"C2":"fa","C3":3}],"D":"HH","E":0,"F":6}]
[{"A":"5","B":"811","C":[{"C1":1,"C2":"da","C3":3}],"D":"HH","E":0,"F":6}]
You can directly run and see the output here.
Once you have those payloads separated in valid JSON structure, you can feed these to you JSON parser.
I don't speak English well
So the question may be a bit odd
{
"arg1": {
"1": "1",
"2": "2"
},
"arg2": {
"1": "1",
"2": "2"
},
"arg3": {
"1": "1",
"2": "2"
}
}
I want to store data this way. What should I do?
json_data = {arg3: {"1": "1", "2": "2"}}
with open(f'./Json/test.json', 'w', encoding='utf-8') as make_file:
json.dump(json_data, make_file, ensure_ascii=False ,indent="\t")
Is this right?
I would appreciate it if you let me know.
I don't know what to do by deleting the original content.
Your code works fine. The only problem I see when your running it is that that arg3 needs to be written as "arg3" in double quotes (single quotes are invalid in json) unless you have a value for it defined previously.
json_data = {"arg3": {"1": "1", "2": "2"}}
Make that change, and you should be able to load and properly display your JSON with:
with open(f'output.json') as f:
a = json.load(f)
print(json.dumps(a, indent="\t"))
If you do the json.dumps() you get a properly formatted json which you can then call print on to display.