convert delimited string to hierarchical JSON in python - python

How do I convert delimited strings into a hierarchical JSON in Python? (I saw a solution for a similar question in jQuery. I have been trying to find a Python solution for the same.)
The goal is to generate a hierarchical JSON of categories from a bunch of URLs which might look like:
sport/tennis/grandslams
sport/chess
sport/chess/players/men
sport/tennis
sport/cricket/stadiums
sport/tennis/players

You could achieve this with dictionnaries :
initial = ["Fred-Jim","Fred","Fred-Jim-Bob", "Fred-Jim-Jack", "John", "John-Jim"]
result = {}
for item in initial:
hierarchy = item.split('-')
local_result = result
for node in hierarchy:
local_result = local_result.setdefault(node, {})
print result
Will give you :
{
'John': {
'Jim': {}
},
'Fred': {
'Jim': {
'Bob': {},
'Jack': {}
}
}
}

Are you looking for json.dumps() from the json module?
edit:
oh, ok, I get you now. Maybe something like:
#paths is a list of strings containing the paths you are scraping from your site.
hierarchy = {}
for path in paths:
cursor = hierarchy
for part in path.split('/'):
if part not in cursor:
cursor[part] = {}
cursor = cursor[part]

Related

Python: How to look up a specific key in json and add values ​to it?

I need to look for a key in json e add some info that come from a SQl query.
The problem is how to look for this specific key and add the info.
Here's a example:
{
"charts":{
"chart_file": "Z1.xml",
"chart_path":"...path_to_chart",
"modified":"date",
"chart_tags":{}
}
}
The query give me info about the "chart_tags" and initially its empty.
Assuming there are 3 different tags, I would like to add the information being the tag name the main key and inside it the information of colors, scales and ID.
Here's a desired output:
{
"charts":{
"chart_file": "Z1.xml",
"chart_path":"...path_to_chart",
"modified":"date",
"chart_tags":{
"tagNAME":{
"tagID":1,
"scale":"[0,100]",
"color":"#000000"
},
"tagNAME2":{
"tagID":2,
"scale":"[0,5]",
"color":"#e3dc19"
},
"tagNAME3":{
"tagID":3,
"scale":"[20,80]",
"color":"#23fa67"
}
}
}
}
I've been trying to add the information in a dict and right after a json.dump, but I've been having problems with the dict not being hashable.
Here's what i tryed and thanks for the help
jsonFile = open('teste.config', 'r', encoding='utf-8-sig')
millexcsMills = json.load(jsonFile)
currentMill=millexcsMills["mills"][millName]
for x, y,z,w in zip(df1.columns.tolist()[1:], chartTrendColors,chartTrendScales,chartTagID):
data = {
"tagName":x,
"color":y,
"scale": z,
"tagID":w,
}
millexcsMills['mills'][currentMill]['charts']['chart_tags'].append(data)
with open('teste.config', 'w') as outfile:
json.dump(jsonFile, outfile, indent=6)

python - Json data with different keys

I am trying to store two run options in Json. My attempt is as below. Is this a sensible way to organise Json object? Also how can I read either of them into tuples? I tried tuple([(item['opt_one'],item['val_one']) for item in config['opts']]) but git a key error. Many thanks for your help.
"opts":[
{
"opt_one": "one_option",
"val_one" : "value_one"
},
{
"opt_two": "two_option",
"val_two" : "value_two"
}
]
# or it can be done in 1 line
print(tuple(map(lambda v: tuple(v.values()), J['opts'])))
import json
j = """
{"opts":[
{
"opt_one": "one_option",
"val_one" : "value_one"
},
{
"opt_two": "two_option",
"val_two" : "value_two"
}
]
}
"""
# note the braces around "opts"
J = json.loads(j) #turns it into a python object
print(J) #see!
# the long way to do it, but you can see the process
R = []
for item in J['opts']:
r = []
for v in item.values():
r.append(v)
R.append(tuple(r))
print(tuple(R)) # solution

How do I extract a list item from nested json in Python?

I have a json object and I'm trying to extract a couple of values from a nested list. Then print them in markup. I'm getting and error - AttributeError: 'list' object has no attribute 'get'
I understand that it's a list and I can't preform a get. I've been searching for the proper method for a few hours now and I'm running out of steam. I'm able to get the Event, but not Value1 and Value2.
This is the json object
{
"resource": {
"data": {
"event": "qwertyuiop",
"eventVersion": "1.05",
"parameters": {
"name": "sometext",
"othername": [
""
],
"thing": {
"something": {
"blah": "whatever"
},
"abc": "123",
"def": {
"xzy": "value"
}
},
"something": [
"else"
]
},
"whatineed": [{
"value1": "text.i.need",
"value2": "text.i.need.also"
}]
}
}
}
And this is my function
def parse_json(json_data: dict) -> Info:
some_data = json_data.get('resource', {})
specific_data = some_data.get('data', {})
whatineed_data = specific_data.get('whatineed', {})
formatted_json = json.dumps(json_data, indent=2)
description = f'''
h3. Details
*Event:* {some_data.get('event')}
*Value1:* {whatineed_data('value1')}
*Value2:* {whatineed_data('value2')}
'''
From the data structure, whatineed is a list with a single item, which in turn is a dictionary. So, one way to access it would be:
whatineed_list = specific_data.get('whatineed', [])
whatineed_dict = whatineed_list[0]
At this point you can do:
value1 = whatineed_dict.get('value1')
value2 = whatineed_dict.get('value2')
You can change your function to the following:
def parse_json(json_data: dict) -> Info:
some_data = json_data.get('resource')
specific_data = some_data.get('data', {})
whatineed_data = specific_data.get('whatineed', {})
formatted_json = json.dumps(json_data, indent=2)
description = '''
h3. Details
*Event:* {}
*Value1:* {}
*Value2:* {}
'''.format(some_data.get('data').get('event'),whatineed_data[0]['value1'], whatineed_data[0]['value2'])
Since whatineed_data is a list, you need to index the element first
Python handles json as strings unless they are coming directly from a file. This could be the source for some of your problems. Also this article might help.
Assuming that "whatineed" attribute is really a list, and it's elements are dicts, you can't call whatineed.get asking for Value1 or Value2 as if they are attributes, because it is a list and it don't have attributes.
So, you have two options:
If whatineed list has a single element ever, you can access this element directly and than access the element attributes:
element = whatineed[0]
v1 = element.get('value1', {})
v2 = element.get('value2', {})
Or, if whatineed list can have more items, so, you will need to iterate over this list and access those elements:
for element in whatineed:
v1 = element.get('value1', {})
v2 = element.get('value2', {})
## Do something with values

Logic for building converter using python dictionary values

I have such slice of loaded json tp python dictionary (size_dict):
{
"sizeOptionName":"XS",
"sizeOptionId":"1528",
"sortOrderNumber":"7017"
},
{
"sizeOptionName":"S",
"sizeOptionId":"1529",
"sortOrderNumber":"7047"
},
{
"sizeOptionName":"M",
"sizeOptionId":"1530",
"sortOrderNumber":"7095"
}
and I have products with size Id (dictionary_prod):
{
"catalogItemId":"7627712",
"catalogItemTypeId":"3",
"regularPrice":"0.0",
"sizeDimension1Id":"1528",
"sizeDimension2Id":"0",
}
I need to make such as output for any product:
result_dict = {'variant':
[{"catalogItemId":"7627712", ...some other info...,
'sizeName': 'XS', 'sizeId': '1525'}}]}
so I need to convert size ID and add it to new result object
What is the best pythonic way to do this?
I dont know how to get right data from size_dict
if int(dictionary_prod['sizeDimension1Id']) > o:
(result_dict['variant']).append('sizeName': size_dict???)
As Tommy mentioned, this is best facilitated by mapping the size id's to their respective dictionaries.
size_dict = \
[
{
"sizeOptionName":"XS",
"sizeOptionId":"1528",
"sortOrderNumber":"7017"
},
{
"sizeOptionName":"S",
"sizeOptionId":"1529",
"sortOrderNumber":"7047"
},
{
"sizeOptionName":"M",
"sizeOptionId":"1530",
"sortOrderNumber":"7095"
}
]
size_id_map = {size["sizeOptionId"] : size for size in size_dict}
production_dict = \
[
{
"catalogItemId":"7627712",
"catalogItemTypeId":"3",
"regularPrice":"0.0",
"sizeDimension1Id":"1528",
"sizeDimension2Id":"0",
}
]
def make_variant(idict):
odict = idict.copy()
size_id = odict.pop("sizeDimension1Id")
odict.pop("sizeDimension2Id")
odict["sizeName"] = size_id_map[size_id]["sizeOptionName"]
odict["sizeId"] = size_id
return odict
result_dict = \
{
"variant" : [make_variant(product) for product in production_dict]
}
print(result_dict)
Your question is a little confusing but it looks like you have a list (size_dict) of dictionaries that contain some infroamtion and you want to do a lookup to find a particular element in the list that contains the SizeOptionName you are interested in so that you can read off the SizeOptionID.
So first you could organsie your size_dict as a dictionary rather than a list - i.e.
sizeDict = {"XS":{
"sizeOptionName":"XS",
"sizeOptionId":"1528",
"sortOrderNumber":"7017"
}, "S": {
"sizeOptionName":"S",
"sizeOptionId":"1529",
"sortOrderNumber":"7047"
}, ...
You could then read off the SizeOptionID you need by doing:
sizeDict[sizeNameYouAreLookingFor][SizeOptionID]
Alternative you could keep your current structure and just search the list of dictionaries that is size_dict.
So:
for elem in size_dict:
if elem.SizeOptionID == sizeYouAreLookingFor:
OptionID = elem.SizeOptionId
Or perhaps you are asking something else?

Serialize Dictionary with a string key and List[] value to JSON

How can I serialize a python Dictionary to JSON and pass back to javascript, which contains a string key, while the value is a List (i.e. [])
if request.is_ajax() and request.method == 'GET':
groupSet = GroupSet.objects.get(id=int(request.GET["groupSetId"]))
groups = groupSet.groups.all()
group_items = [] #list
groups_and_items = {} #dictionary
for group in groups:
group_items.extend([group_item for group_item in group.group_items.all()])
#use group as Key name and group_items (LIST) as the value
groups_and_items[group] = group_items
data = serializers.serialize("json", groups_and_items)
return HttpResponse(data, mimetype="application/json")
the result:
[{"pk": 5, "model": "myApp.group", "fields": {"name": "\u6fb4\u9584", "group_items": [13]}}]
while the group_items should have many group_item and each group_item should have "name", rather than only the Id, in this case the Id is 13.
I need to serialize the group name, as well as the group_item's Id and name as JSON and pass back to javascript.
I am new to Python and Django, please advice me if you have a better way to do this, appreciate. Thank you so much. :)
Your 'groups' variable is a QuerySet object, not a dict. You will want to be more explicit with the data that you want to return.
import json
groups_and_items = {}
for group in groups:
group_items = []
for item in group.group_items.all():
group_items.append( {'id': item.id, 'name': item.name} )
# <OR> if you just want a list of the group_item names
#group_items = group.group_items.all().values_list('name', flat=True)
groups_and_items[group.name] = group_items
data = json.dumps(groups_and_items)
What exactly did you want you want your data to look like? The above should give you data like this :
[{ 'groupA': [{'id': 1, 'name': 'item-1'}],
'groupB': [{'id': 2, 'name': 'item-2'}, ...],
'groupC': []
}]
Or this if you just want the list of group_item names:
[{ 'groupA': ['item-1'],
'groupB': ['item-2', ...],
'groupC': []
}]
You should use Python's json module to encode your JSON.
Also, what indentation level do you have data = serializers at? It looks like it could be inside the for loop?

Categories