I'm currently learning python and I'm familiar (still beginner) with json
my goal is to have one json with many lookup list that could have duplicated value but different key
instead of having duplication of list, I'm trying to find a way to only have one copy and then reusing, i have made htis simple example;
import json
json_enum1 = '{"01" : "ab", "02" : "cd"}'
json_enum2 = '{"01" : "zz", "02" : "xx"}'
json_string = '{"val1": null, "val2": null, "val3": null}'
parsed_json = json.loads(json_string)
parsed_enum1 = json.loads(json_enum1)
parsed_enum2 = json.loads(json_enum2)
parsed_json['val1'] = parsed_enum1
parsed_json['val2'] = parsed_enum2
parsed_json['val3'] = parsed_enum1
print(parsed_json)
print(parsed_json['val1']['01'])
print(parsed_json['val2']['01'])
print(parsed_json['val3']['02'])
result
{u'val3': {u'02': u'cd', u'01': u'ab'}, u'val2': {u'02': u'xx', u'01':
u'zz'}, u'val1': {u'02': u'cd', u'01': u'ab'}}
ab
zz
cd
I could also do that:
import json
json_string = '{"val1": {"01" : "ab", "02" : "cd"}, "val2": {"01" : "zz", "02" : "xx"}, "val3": {"01" : "ab", "02" : "cd"}}'
parsed_json = json.loads(json_string)
print(parsed_json)
print(parsed_json['val1']['01'])
print(parsed_json['val2']['01'])
print(parsed_json['val3']['02'])
which give the same result but now if json_enum1 change, i need to change it twice
and this is a very small example, the real data is way bigger
my question is; is there a better way of doing what I'm describing/showing?
Related
I have JSON data in a file json_format.py as follows:
{
"name" : "ramu",
"place" : "hyd",
"height" : 5.10,
"list" : [1,2,3,4,5,6],
"tuple" : (0,1,2),
"colors" : {"mng":"white","aft" : "blue","night":"red"},
"car" : "None",
"bike" : "True",
}
I'm reading the above with this code:
import json
from pprint import pprint
with open (r'C:/PythonPrograms\Json_example/json_format.py') as jobj:
fp = jobj.readlines()
b = json.dumps(fp) # ---> I get string
print(type(b))
c = json.loads(b)
print(type(c)) # ---> List
pprint(c)
print(c[0])
pprint(c["name"])
Now, I would like to access the JSON object as c['name'] and the output should be ramu.
Since c is a list, I can't do so. How can I read my JSON data so that I can access it with keys?
Thanks in advance!
You're effectively doing c = json.loads(json.dumps(jobj.readlines())) when you just need:
c = json.load(jobj)
print(c["name"]) # ramu
Also, your JSON is malformed.
There are no tuples in JSON: "tuple" : (0,1,2),
Your last item should not end with a comma: "bike" : "True",
I have retrieved remote json using urllib.request in python3 and would like to to dump, line by line, the value of the IP addresses only (ie. ip:127.0.0.1 would be 127.0.0.1, next line is next IP) if it matches certain criteria. Other key values include a score (one integer value per category) and category (one or more string values possible).
I want to check if the score is higher than, say 10, AND the category number equals a list of one OR more values. If it fits the params, I just need those IP addresses added line by line to a text file.
Here is how I retrieve the json:
ip_fetch = urllib.request.urlopen('https://testonly.com/ip.json').read().decode('utf8')
I have the json module loaded, but don't know where to go from here.
Example of json data I'm working with, more than one category:
"127.0.0.1" : {
"Test" : "10",
"Prod" : "20"
},
I wrote a simple example that should show you how to iterate trough json objects and how to write to a file:
import json
j = json.loads(test)
threshold = 10
validCategories = ["Test"]
f=open("test.txt",'w')
for ip, categories in j.items():
addToList = False
for category, rank in categories.items():
if category in validCategories and int(rank) >= threshold:
addToList = True
if addToList:
f.write("{}\n".format(ip))
f.close()
I hope that helps you to get started. For testing I used the following json-string:
test = """
{
"127.0.0.1" : {
"Test" : "10",
"Prod" : "20"
},
"127.0.0.2" : {
"Test" : "5",
"Prod" : "20"
},
"127.0.0.3" : {
"Test" : "5",
"Prod" : "5",
"Test2": "20"
}
}
"""
import urllib.request as request
import json
api = "https://kr.api.pvp.net/championmastery/location/KR/player/38281748/topchampions?api_key=RGAPI-6bdee369-a91d-485a-9280-444de0e37afe"
api_data = request.urlopen(api).read().decode("utf-8")
apiload = json.loads(api_data)
print(apiload)
I want to print my League of Legends champion Points.
So I use https://developer.riotgames.com/api/methods#!/1091/3768 this API, and
convert to Python object. but this API's Return Value is List[ChampionMasteryDTO],
which means I can't use it as dictionary.
apiload contain [{"key" : "value"}, ... {"key" : "value"}]
how can I make apiload as dictionary?
The apiload variable prints two dictionaries within a list.
If you would like to create a new dictionary using the apiload you can do the following:
#create a new dictionary
my_dict = {}
#now iterate through the list
for item in apiload:
#now iterate through the dictionaries that are in the list:
for key, value in item.items():
#assign the key value to the new declared dictionary
new_dict[key] = value
This will create a new dictionary with the following output:
championId : 91
tokensEarned : 0
championPointsSinceLastLevel : 339079
chestGranted : True
lastPlayTime : 1478451844000
playerId : 38281748
championLevel : 7
championPoints : 360679
championPointsUntilNextLevel : 0
championId : 5
tokensEarned : 0
championPointsSinceLastLevel : 129110
chestGranted : True
lastPlayTime : 1478454752000
playerId : 38281748
championLevel : 7
championPoints : 150710
championPointsUntilNextLevel : 0
championId : 21
tokensEarned : 0
championPointsSinceLastLevel : 2018
chestGranted : False
lastPlayTime : 1476197348000
playerId : 38281748
championLevel : 4
championPoints : 14618
championPointsUntilNextLevel : 6982
Hope that helps.
Regarding the structure of your response, the easy one if you just want to print your points, would be to just use a loop actually :
for el in apiload:
print(el["championPoints"])
If your problem is to print the total of points collected, use a collections.Counter :
from collections import Counter
cnt = Counter()
for col in apiload:
for k in col.keys():
cnt[k] += c.get(k, 0)
print(cnt['championPoints']) # should print the sum of championPoints
I've wrote a program which process JSON objects. Now I want to verify if I've missed something.
Is there an JSON-example of all allowed JSON structure combinations? Something like this:
{
"key1" : "value",
"key2" : 1,
"key3" : {"key1" : "value"},
"key4" : [
[
"string1",
"string2"
],
[
1,
2
],
...
],
"key5" : true,
"key6" : false,
"key7" : null,
...
}
As you can see at http://json.org/ on the right hand side the grammar of JSON isn't quite difficult, but I've got several exceptions because I've forgotten to handles some structure combinations which are possible. E.g. inside an array there can be "string, number, object, array, true, false, null" but my program couldn't handle arrays inside an array until I ran into an exception. So everything was fine until I got this valid JSON object with arrays inside an array.
I want to test my program with a JSON object (which I'm looking for). After this test I want to be feel certain that my program handle every possible valid JSON structure on earth without an exception.
I don't need nesting in depth 5 or so. I only need something in nested depth 2 or max 3. With all base types which nested all allowed base types, inside this base type.
Have you thought of escaped characters and objects within an object?
{
"key1" : {
"key1" : "value",
"key2" : [
"String1",
"String2"
],
},
"key2" : "\"This is a quote\"",
"key3" : "This contains an escaped slash: \\",
"key4" : "This contains accent charachters: \u00eb \u00ef",
}
Note: \u00eb and \u00ef are resp. charachters ë and ï
Choose a programming language that support json.
Try to load your json, on fail the exception's message is descriptive.
Example:
Python:
import json, sys;
json.loads(open(sys.argv[1]).read())
Generate:
import random, json, os, string
def json_null(depth = 0):
return None
def json_int(depth = 0):
return random.randint(-999, 999)
def json_float(depth = 0):
return random.uniform(-999, 999)
def json_string(depth = 0):
return ''.join(random.sample(string.printable, random.randrange(10, 40)))
def json_bool(depth = 0):
return random.randint(0, 1) == 1
def json_list(depth):
lst = []
if depth:
for i in range(random.randrange(8)):
lst.append(gen_json(random.randrange(depth)))
return lst
def json_object(depth):
obj = {}
if depth:
for i in range(random.randrange(8)):
obj[json_string()] = gen_json(random.randrange(depth))
return obj
def gen_json(depth = 8):
if depth:
return random.choice([json_list, json_object])(depth)
else:
return random.choice([json_null, json_int, json_float, json_string, json_bool])(depth)
print(json.dumps(gen_json(), indent = 2))
So I'm trying to pull data from a JSON string (as seen below). When I decode the JSON using the code below, and then attempt to index the duration text, I get a nil return. I have tried everything and nothing seems to work.
Here is the Google Distance Matrix API JSON:
{
"destination_addresses" : [ "San Francisco, CA, USA" ],
"origin_addresses" : [ "Seattle, WA, USA" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "1,299 km",
"value" : 1299026
},
"duration" : {
"text" : "12 hours 18 mins",
"value" : 44303
},
"status" : "OK"
}]
}],
"status" : "OK"
}
And here is my code:
local json = require ("json")
local http = require("socket.http")
local myNewData1 = {}
local SaveData1 = function (event)
distanceReturn = ""
distance = ""
local URL1 = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=Seattle&destinations=San+Francisco&mode=driving&&sensor=false"
local response1 = http.request(URL1)
local data2 = json.decode(response1)
if response1 == nil then
native.showAlert( "Data is nill", { "OK"})
print("Error1")
distanceReturn = "Error1"
elseif data2 == nill then
distanceReturn = "Error2"
native.showAlert( "Data is nill", { "OK"})
print("Error2")
else
for i = 1, #data2 do
print("Working")
print(data2[i].rows)
for j = 1, #data2[i].rows, 1 do
print("\t" .. data2[i].rows[j])
for k = 1, #data2[i].rows[k].elements, 1 do
print("\t" .. data2[i].rows[j].elements[k])
for g = 1, #data2[i].rows[k].elements[k].duration, 1 do
print("\t" .. data2[i].rows[k].elements[k].duration[g])
for f = 1, #data2[i].rows[k].elements[k].duration[g].text, 1 do
print("\t" .. data2[i].rows[k].elements[k].duration[g].text)
distance = data2[i].rows[k].elements[k].duration[g].text
distanceReturn = data2[i].rows[k].elements[k].duration[g].text
end
end
end
end
end
end
timer.performWithDelay (100, SaveData1, 999999)
Your loops are not correct. Try this shorter solution.
Replace all your "for i = 1, #data2 do" loop for this one below:
print("Working")
for i,row in ipairs(data2.rows) do
for j,element in ipairs(row.elements) do
print(element.duration.text)
end
end
This question was solved on Corona Forums by Rob Miracle (http://forums.coronalabs.com/topic/47319-parsing-json-from-google-distance-matrix-api/?hl=print_r#entry244400). The solution is simple:
"JSON and Lua tables are almost identical data structures. In this case your table data2 has top level entries:
data2.destination_addresses
data2.origin_addresses
data2.rows
data2.status
Now data2.rows is another table that is indexed by numbers (the [] brackets) but here is only one of them, but its still an array entry:
data.rows[1]
Then inside of it is another numerically indexed table called elements.
So far to get to the element they are (again there is only one of them
data2.rows[1].elements[1]
then it's just accessing the remaining elements:
data2.rows[1].elements[1].distance.text
data2.rows[1].elements[1].distance.value
data2.rows[1].elements[1].duration.text
data2.rows[1].elements[1].duration.value
There is a great table printing function called print_r which can be found in the community code which is great for dumping tables like this to see their structure."