I'm in the process of generating a json file from python, however, i'd like separate the dictionaries via a comma after each loop, here's a portion of the code:
listA = [computer1,computer2]
listB = [computertype1,computertype2]
for computer, item in zip(listA,listB):
mydict = {
"Computertype": "somevalue",
"computer": [
computer
],
"targert": {
"item": item
}
},
The desired output should be:
[
{
"Computertype": "somevalue",
"computer": [
computer1
],
"targert": {
"item": computertype1
}
},
{
"Computertype": "somevalue",
"computer": [
computer2
],
"targert": {
"item": computertype2
}
}
]
So basically a comma right after the first end brace of the first loop: }, and all in one list, one bracket on top and one closing bracket at the bottom.
When running the code, it doesn't show the comma after each brace in the loop, and it does input each loop within a list automatically, any suggestions ?
What I get:
[ {
"Computertype": "somevalue",
"computer": [
computer1
],
"targert": {
"item": computertype1
}
}
]
[ {
"Computertype": "somevalue",
"computer": [
computer2
],
"targert": {
"item": computertype2
}
}]
I think this is what your looking for:
listA = [computer1,computer2]
listB = [computertype1,computertype2]
mylist = []
for computer, item in zip(listA,listB):
mydict = {
"Computertype": "somevalue",
"computer": [
computer
],
"target": {
"item": item
}
}
mylist.append(mydict)
print(mylist)
Related
I have a requirement wherein the output JSON field needs to have an escaped double quotes ("). I managed to have the quotes escaped in the field values by hardcoding the quotes. But now, I'm not so sure on how to put a backslash in the start and end of the field.
Please see sample below:
{ "Request":
[ {
"content": { "row": [
{ "fieldA": [ "tax\":\"US\",\"percent\": 6.250000000,\"value\": 10000.000000000,\"description\":\"TaxUS\",\"currency\":\"USD" ]},
{"fieldA": [ "tax\":\"\",\"percent\": 0.000000000,\"value\": 170000.000000000,\"description\":\"Total\",\"currency\":\"USD" ] },
{ "fieldB": [ "item\":\"000000\",\"Line\":0000,\"Date\":\"20201207\",\"Qty\": 2000,\"confirm\": 0.00" ] },
{"fieldB": [ "item\":\"000001\",\"Line\":0001,\"Date\":\"20201208\",\"Qty\": 1000,\"confirm\": 2000.00" ] } ] } }
I need to have a backslash at the beginning and the end of the fieldA and fieldB arrays.
This is the expected output:
{ "Request":
[ {
"content": { "row": [
{ "fieldA": [ \"tax\":\"US\",\"percent\": 6.250000000,\"value\": 10000.000000000,\"description\":\"TaxUS\",\"currency\":\"USD\" ]},
{"fieldA": [ \"tax\":\"\",\"percent\": 0.000000000,\"value\": 170000.000000000,\"description\":\"Total\",\"currency\":\"USD\" ] },
{ "fieldB": [ \"item\":\"000000\",\"Line\":0000,\"Date\":\"20201207\",\"Qty\": 2000,\"confirm\": 0.00\" ] },
{"fieldB": [ \"item\":\"000001\",\"Line\":0001,\"Date\":\"20201208\",\"Qty\": 1000,\"confirm\": 2000.00\" ] } ] } }
I would like to ask for tips in adding the backslash for the requirement.
Thanks everyone!
I may not discribed it properly, I tried many times and looked up the manaual on jq Manaual , and i got no idea how to insert object which contains array into a json file by jq command, anyway, here is the origin test.json:
[
{
"gate": [
{
"pro1": "1"
}
],
"home": [
{
"mem1": "1"
}
],
"holder": "1"
}
]
And i wish to be like this after insert:
[
{
"gate": [
{
"pro1": "1"
}
],
"home": [
{
"mem1": "1"
}
],
"holder": "1"
},
{
"gate": [
{
"pro1": "2"
}
],
"home": [
{
"mem1": "2"
}
],
"holder": "1"
}
]
Could it possibly done by jq?
Since you haven't provided more detail I am going to assume that you simply want to append a hard-coded object to an existing array. (If that's not what you mean you'll need to be more precise in your question.)
You can add items to the end of a list with the + operator. So in your case:
jq '.+[{"gate":[{"pro1": "2"}], "home":[{"mem1": "2"}],"holder": "1"}]' input.json
[
{
"gate": [
{
"pro1": "1"
}
],
"home": [
{
"mem1": "1"
}
],
"holder": "1"
},
{
"gate": [
{
"pro1": "2"
}
],
"home": [
{
"mem1": "2"
}
],
"holder": "1"
}
]
The . takes the existing input, which is an array. The +[ {...} ] concatenates it with another array of one object. If you want to put the new item(s) at the start instead of the end, swap it round: [ {...} ]+.
I'm having some problem to write a query to return a triple nested value from a document. The documents I'm using are structured like this
{
"areaname": "name1",
"places": [
{
"placename": "place1",
"objects": [
{
"objname": "obj1",
"tags": [
"tag1",
"tag2"
]
},
{
"objname": "obj2",
"tags": [
"tag6",
"tag7"
]
}
]
},
{
"placename": "place2",
"objects": [
{
"objname": "obj45",
"tags": [
"tag46",
"tag34"
]
},
{
"objname": "obj77",
"tags": [
"tag56",
"tag11"
]
}
]
}
]
}
It is quite simple actually but I can't find a solution to a simple query like:
"return the objname of the object that contains tag1 inside their tag"
So for the give document if I use "tag1" as a parameter it is expected for the query to return "obj1"
It should give me the same result if I use "tag2" as a parameter
Other example: using "tag56" it should return only "obj77"
Right now i have no problem returning the whole document using the dot-notation or top level field such as areaname or others
db.users.find( {"places.objects.tags":"tag1"}, { areaname: 1, _id:0 } )
Is this even possible?
Keeping it simple:
[
{
"$match" : {
"places.objects.tags" : "tag1"
}
},
{
"$unwind" : "$places"
},
{
"$unwind" : "$places.objects"
},
{
"$match" : {
"places.objects.tags" : "tag1"
}
},
{
"$group" : {
"_id" : "$_id",
"obj_names" : {
"$push" : "$places.objects.objname"
}
}
}
],
You should add any other fields you want to keep to the group stage,
this can also be done without the double $unwind stage but i choose this for read-ability.
So I'm trying to convert a nested dictionary like:
A = {
"root":
{
"child1":
{
"child11":"hmm",
"child12":"not_hmm"
},
"child2":"hello"
}
}
To this:
{
"name":"root",
"children": [
{"name":"child1",
"children" :
[{"name":"child11",
"children":[{"name":"hmm"}]}
{"name":"child12",
"children":[{"name":"not_hmm"}]}
]
},
{"name":"child2",
"children":[{"name":"hello"}]
}
]
}
I need this, since I'm trying to visualize it with this graph drawing template: Collapsible Tree
I'm having some trouble creating a recursive method that is capable of this transformation.
Preferably in python3. So far I have:
def visit(node, parent=None):
B = {}
for k,v in node.items():
B["name"]=k
B["children"] = []
if isinstance(v,dict):
print("Key value pair is",k,v)
B["children"].append(visit(v,k))
new_dict = {}
new_dict["name"]=v
return [new_dict]
C = visit(A) # This should have the final result
But its wrong. Any help is appreciated.
We'll have a function that takes a root (assuming it has only one entry), and returns a dict, as well as a helper function that returns lists of dicts.
def convert(d):
for k, v in d.items():
return {"name": k, "children": convert_helper(v)}
def convert_helper(d):
if isinstance(d, dict):
return [{"name": k, "children": convert_helper(v)} for k, v in d.items()]
else:
return [{"name": d}]
which gives us
json.dumps(convert(A), indent=2)
{
"name": "root",
"children": [
{
"name": "child1",
"children": [
{
"name": "child11",
"children": [
{
"name": "hmm"
}
]
},
{
"name": "child12",
"children": [
{
"name": "not_hmm"
}
]
}
]
},
{
"name": "child2",
"children": [
{
"name": "hello"
}
]
}
]
}
I have this file:
[
"smoke-tests",
"push-apps-manager"
]
I'd like to get this output using JQ:
{
"errands": [
{"name": "smoke-tests", "post_deploy": true},
{"name": "push-apps-manager", "post_deploy": true}
]
}
It seems so simple, yet, I have so much difficulty here...
It's a little tricky, since you need to embed the input into the list bound to the errands key. Start by creating the sequence of name/post_deploy objects:
% jq '.[] | {name: ., post_deploy: true}' names.json
{
"name": "smoke-tests",
"post_deploy": true
}
{
"name": "push-apps-manager",
"post_deploy": true
}
Then wrap that in the list in the outer object:
% jq '{errands: [.[] | {name: ., post_deploy: true}]}' names.json
{
"errands": [
{
"name": "smoke-tests",
"post_deploy": true
},
{
"name": "push-apps-manager",
"post_deploy": true
}
]
}
You can also use the map function (which I rarely remember how to use correctly, but it turns out is pretty simple here):
% jq '{errands: map({name:., post_deploy: true})}' names.json
Here is another approach. If you are new to jq it may be easiest to work towards the goal in small steps.
1) Start with the identity filter
.
which produces as expected
[
"smoke-tests",
"push-apps-manager"
]
2) next add the outer object with the "errands" key:
{ "errands": . }
which produces
{
"errands": [
"smoke-tests",
"push-apps-manager"
]
}
3) next move the data into an array
{ "errands": [ . ] }
which produces
{
"errands": [
[
"smoke-tests",
"push-apps-manager"
]
]
}
4) add the inner object with the "name" and "post_deploy" keys
{ "errands": [ { "name": ., "post_deploy": true } ] }
which produces
{
"errands": [
{
"name": [
"smoke-tests",
"push-apps-manager"
],
"post_deploy": true
}
]
}
5) Now we're really close. All we need to do is take advantage of jq's Object Construction behavior when an expression produces multiple results :
{ "errands": [ { "name": .[], "post_deploy": true } ] }
which gives us the desired result
{
"errands": [
{
"name": "smoke-tests",
"post_deploy": true
},
{
"name": "push-apps-manager",
"post_deploy": true
}
]
}