'Convert string like dict into dict format [closed]
I have a string that looks like the following:
{
change:"2.429993",
changePercent:"1.475316",
dayVolume:10222078,
exchange:NYQ,
id:CVX,
marketHours:1,
price:"167.14",
priceHint:4,
quoteType:8,
time:3304930430000,
}
I want to try and make this into a dict. I know that I can use json.loads
to achieve this, however I do not know how to get the keys
with double brackets.
Additionally, when I try parsing the string with the following:
type_of_dict.split(":")
It gives the following:
['{\nchange', '"2.429993",\nchangePercent', '"1.475316",\ndayVolume', '10222078,\nexchange', 'NYQ,\nid', 'CVX,\nmarketHours', '1,\nprice', '"167.14",\npriceHint', '4,\nquoteType', '8,\ntime', '3304930430000,\n}']
I can get it into a dict with a rather tedious process and was wondering if there are cleaner alternatives:
from collections import defaultdict
type_of_dict.split(":")
type_of_dict=[x.split(",\n") for x in type_of_dict]
keys=[x[1] for x in type_of_dict[1:]][:-1]
keys =[[x.split('\n') for x in type_of_dict[0]][0][1]] + keys
values = [x[0] for x in type_of_dict[1:]]
symbols = defaultdict(list)
for k, v in zip(keys, values):
symbols[k].append(v)
print(symbols)
defaultdict(<class 'list'>, {
'change': ['"2.429993"'],
'changePercent': ['"1.475316"'],
'dayVolume': ['10222078'],
'exchange': ['NYQ'],
'id': ['CVX'],
'marketHours': ['1'],
'price': ['"167.14"'],
'priceHint': ['4'],
'quoteType': ['8'],
'time': ['3304930430000']
})
The script I used to grab the data:
import os
from subprocess import STDOUT, check_call as x
cmd1 = r'/Applications/StockSpy Realtime Stocks Quote.app/Contents/MacOS/StockSpy Realtime Stocks Quote'
with open(os.devnull, 'rb') as DEVNULL, open('output.txt', 'wb') as f:
data=x(cmd1, stdout=f, stderr=STDOUT)
with open('output.txt', 'r') as f:
data=re.findall(r'\bsymbols:\s*\(\s*{[^{}]*}\s*\)', f.read())
Solution 1:[1]
Could you provide more test data/records?
import yaml
from pprint import pprint
data = """{
change:"2.429993",
changePercent:"1.475316",
dayVolume:10222078,
exchange:NYQ,
id:CVX,
marketHours:1,
price:"167.14",
priceHint:4,
quoteType:8,
time:3304930430000,
}"""
result_dict = yaml.safe_load(data.replace(':', ': '))
pprint(result_dict)
Result:
{'change': '2.429993',
'changePercent': '1.475316',
'dayVolume': 10222078,
'exchange': 'NYQ',
'id': 'CVX',
'marketHours': 1,
'price': '167.14',
'priceHint': 4,
'quoteType': 8,
'time': 3304930430000}
After that if you want to cast types you can use pydantic:
from pydantic import BaseModel
class Record(BaseModel):
change: float
changePercent: float
dayVolume: int
exchange: str
id: str
marketHours: int
price: float
priceHint: int
quoteType: int
time: int
dict(Record(**result_dict))
Result:
{'change': 2.429993,
'changePercent': 1.475316,
'dayVolume': 10222078,
'exchange': 'NYQ',
'id': 'CVX',
'marketHours': 1,
'price': 167.14,
'priceHint': 4,
'quoteType': 8,
'time': 3304930430000}
Solution 2:[2]
You can use a regular expression to add quotes around each key, then use ast.literal_eval()
to parse it.
import ast
import re
dict_str = re.sub(r'^(.*?):', r"'\1':', type_of_dict)
result = ast.literal_eval(dict_str);
However, this will fail for exchange:NYQ
. NYQ
needs to be in quotes since it should be a string.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Barmar |