Printing every occurance of a specific JSON key - python

I would like to print the value of every occurance in a JSON string with Python.
Here is my JSON:
{
"changed": false,
"results": [{
"arch": "x86_64",
"epoch": "0",
"name": "nagios-plugins-check_ansible",
"nevra": "0:nagios-plugins-check_ansible-20170803-4.1.x86_64",
"release": "4.1",
"repo": "nagios_plugins",
"version": "20170803",
"yumstate": "available"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "nagios-plugins-check_memory",
"nevra": "0:nagios-plugins-check_memory-20170801-19.1.x86_64",
"release": "19.1",
"repo": "nagios_plugins",
"version": "20170801",
"yumstate": "available"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "nagios-plugins-check_radius",
"nevra": "0:nagios-plugins-check_radius-20170802-3.1.x86_64",
"release": "3.1",
"repo": "nagios_plugins",
"version": "20170802",
"yumstate": "available"
}
]
}
I would like to print every occurence of the "nevra" key to the console. I have tried:
import json, sys
obj=json.load(sys.stdin)
i = 0
while True:
try:
print(obj["results"][i]["nevra"])
i = (i + 1)
except IndexError:
exit(0)
but this produces:
NameError: name 'false' is not defined

Simply use:
for result in obj['results']:
print(result['nevra'])
This generates:
>>> for result in obj['results']:
... print(result['nevra'])
...
0:nagios-plugins-check_ansible-20170803-4.1.x86_64
0:nagios-plugins-check_memory-20170801-19.1.x86_64
0:nagios-plugins-check_radius-20170802-3.1.x86_64

You can finish it one line also :
nevra = [ v["nevra"] for v in data['results']]
Output :
['0:nagios-plugins-check_ansible-20170803-4.1.x86_64', '0:nagios-plugins-check_memory-20170801-19.1.x86_64', '0:nagios-plugins-check_radius-20170802-3.1.x86_64']

to print every occurence of the "nevra" key to the console
Discover jq tool:
jq -r '.results[] | if has("nevra") then .nevra else empty end' yourjsonfile
The output:
0:nagios-plugins-check_ansible-20170803-4.1.x86_64
0:nagios-plugins-check_memory-20170801-19.1.x86_64
0:nagios-plugins-check_radius-20170802-3.1.x86_64

Related

How to print matching json element value from nested json string

my_json file has list of nested dicts, I need to print only the username if type==Developer-Verified and it's value==1, I managed to print just the approvals list, unable to to go further.
$ cat myjson_file | python3.6 -c "import sys, json; approvals=json.load(sys.stdin)['currentPatchSet']['approvals']; print(json.dumps(approvals, indent=4))"
[
{
"type": "Developer-Verified",
"description": "Developer-Verified",
"value": "1",
"grantedOn": 1581451370,
"by": {
"name": "Donald Snifer",
"email": "dsnifer#gmail.com",
"username": "dsnifer"
}
},
{
"type": "Code-Review",
"description": "Code-Review",
"value": "2",
"grantedOn": 1581623684,
"by": {
"name": "Brandon Welch",
"email": "bwelch#gmail.com",
"username": "bwelch"
}
},
{
"type": "Developer-Verified",
"description": "Developer-Verified",
"value": "1",
"grantedOn": 1581451370,
"by": {
"name": "Hamlin Damer",
"email": "hdamer#gmail.com",
"username": "hdamer"
}
}
]
$
I need to print just dsnifer hdamer
I tried to move further with below and other logics, and I keep failing
python3.6 -c "import sys, json; approvals=json.load(sys.stdin)['currentPatchSet']['approvals']; print( k for k,v in approvals[0].items())"
Loop inside json and check if type and value meet's the condition if so just print the username.
for ele in jsonData :
if ele['type'] == 'Developer-Verified' and ele['value'] == '1' :
print(ele["by"]["username"], end=" ")

Get specific data from API response using parameter

I'm unsure how to word the title of this question and no doubt there is an easy solution but I am a beginner.
I need to pass a parameter (symbol) to this function and have it return the 'minTradeQuantity'.
def get_exchange_minqtyize(symbol):
return session_auth.query_symbol()['result']
I can retrieve the whole result response with the function like this, but if I add ['result'][0]['minTradeQuantity'] I can retrieve the 'minTradeQuantity' of the first name in the JSON response. How can I filter using the symbol parameter as 'name' to obtain the value I require?
The whole JSON response from the API docs is below:
{
"ret_code": 0,
"ret_msg": "",
"ext_code": null,
"ext_info": null,
"result": [
{
"name": "BTCUSDT",
"alias": "BTCUSDT",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"basePrecision": "0.000001",
"quotePrecision": "0.01",
"minTradeQuantity": "0.0001",
"minTradeAmount": "10",
"minPricePrecision": "0.01",
"maxTradeQuantity": "2",
"maxTradeAmount": "200",
"category": 1,
"innovation": false,
"showStatus": true
},
{
"name": "ETHUSDT",
"alias": "ETHUSDT",
"baseCurrency": "ETH",
"quoteCurrency": "USDT",
"basePrecision": "0.0001",
"quotePrecision": "0.01",
"minTradeQuantity": "0.0001",
"minTradeAmount": "10",
"minPricePrecision": "0.01",
"maxTradeQuantity": "2",
"maxTradeAmount": "200",
"category": 1,
"innovation": false,
"showStatus": true
}
]
}
Go through the result & filter by symbol:
def get_exchange_minqtyize(symbol):
data = session_auth.query_symbol()['result']
for sym_data in data:
if sym_data['name'] == symbol: # assuming the name here is the symbol you're looking for
return sym_data['minTradeQuantity']

Can't Go Past First Dict In JSON File

I'm trying to iterate through a JSON file to search for specific parts and print out that portion of the file. But my code only works for the first dict in the file, anything past that will have my code print out that the part of the JSON file doesn't exit. Here is the JSON file:
[
{
"Name": "Debian",
"Version": "9",
"Install": "apt",
"Owner": "SPI",
"Kernel": "4.9"
},
{
"Name": "Ubuntu",
"Version": "17.10",
"Install": "apt",
"Owner": "Canonical",
"Kernel": "4.13"
},
{
"Name": "Fedora",
"Version": "26",
"Install": "dnf",
"Owner": "Red Hat",
"Kernel": "4.13"
},
{
"Name": "CentOS",
"Version": "7",
"Install": "yum",
"Owner": "Red Hat",
"Kernel": "3.10"
},
{
"Name": "OpenSUSE",
"Version": "42.3",
"Install": "zypper",
"Owner": "Novell",
"Kernel": "4.4"
},
{
"Name": "Arch Linux",
"Version": "Rolling Release",
"Install": "pacman",
"Owner": "SPI",
"Kernel": "4.13"
},
{
"Name": "Gentoo",
"Version": "Rolling Release",
"Install": "emerge",
"Owner": "Gentoo Foundation",
"Kernel": "4.12"
}
]
Here is my Code:
import json
jsonfile = raw_input("Choose a json file: ")
type(jsonfile)
name = input("Type in the name: ")
type(name)
with open (jsonfile) as myfile:
data = myfile.read()
obj = json.loads(data)
for i in obj:
if i["Name"] == name:
print(i["Version"])
break
else:
print("Title not found")
break
So say I enter the name "Debian" I get the version number just fine. But if I type in "Fedora" for example, I get the "Title not found" portion of my code. Which means that the name wasn't in the JSON file but it is. Any help would be appreciated.
For the sake of simplicity:
s = [
{
"Name": "Debian",
"Version": "9",
"Install": "apt",
"Owner": "SPI",
"Kernel": "4.9"
},
{
"Name": "Ubuntu",
"Version": "17.10",
"Install": "apt",
"Owner": "Canonical",
"Kernel": "4.13"
},
{
"Name": "Fedora",
"Version": "26",
"Install": "dnf",
"Owner": "Red Hat",
"Kernel": "4.13"
},
{
"Name": "CentOS",
"Version": "7",
"Install": "yum",
"Owner": "Red Hat",
"Kernel": "3.10"
},
{
"Name": "OpenSUSE",
"Version": "42.3",
"Install": "zypper",
"Owner": "Novell",
"Kernel": "4.4"
},
{
"Name": "Arch Linux",
"Version": "Rolling Release",
"Install": "pacman",
"Owner": "SPI",
"Kernel": "4.13"
},
{
"Name": "Gentoo",
"Version": "Rolling Release",
"Install": "emerge",
"Owner": "Gentoo Foundation",
"Kernel": "4.12"
}
]
Using list-comprehension:
search = 'Fedora'
print([x['Version'] for x in s if x['Name'] == search])
OUTPUT:
['26']
Explanation:
search = 'Fedora'
for elem in s: # for each elem in the list
if elem['Name'] == search: # check if the Name is what you're looking for
print(elem['Version']) # print the Version if it is
OUTPUT:
26
Your loop always ends on the first iteration.
Corrected version:
# ...
for i in obj:
if i["Name"] == name:
print(i["Version"])
break
else:
print("Title not found")
http://book.pythontips.com/en/latest/for_-_else.html
With break you're exiting immediately the for loop as soon as one element doesn't match name, hence the code works only for the first match.
This is how one could write a loop with a break statement
found = False
for i in obj:
if i["Name"] == name:
found = True
break
if found:
print(i["Version"])
else:
print("Title not found")
If the loop is inside a function you could simply use return in place of break
def search(obj, name):
for i in obj:
if i["Name"] == name:
return i["Version"]
return "Title not found"
But the pythonic way to implement this would be:
next((i["Version"] for i in iter(obj) if i["Name"] == name), "Title not found")
next will stop after the first match as well.
Example:
obj= [
{
"Name": "Debian",
"Version": "9"
},
{
"Name": "Ubuntu",
"Version": "17.10"
},
{
"Name": "Fedora",
"Version": "26"
}]
name = "Fedora"
next((i["Version"] for i in iter(obj) if i["Name"] == name), "Title not found")
# Out:
# '26'

How can I fix this regex to match an object in Json and replace it as a list of Object

I have tried the following but i am failing to match the object in Json
:\s*(\{[^\"]*\})
I want to know the way to replace the object type in Json as list of object.
Here is the sample of Json:
{
"resourceType": "ChargeItem",
"id": "example",
"text": {
"status": "generated",
"session": "Done"
},
"identifier": [
{
"system": "http://myHospital.org/ChargeItems",
"value": "654321"
}
],
"definitionUri": [
"http://www.kbv.de/tools/ebm/html/01520_2904360860826220813632.html"
],
"status": "billable",
"code": {
"coding": [
{
"code": "01510",
"display": "Zusatzpauschale für Beobachtung nach diagnostischer Koronarangiografie"
}
]
}
}
I need i want to convert to this form:
{
"resourceType": "ChargeItem",
"id": "example",
"text": [{
"status": "generated",
"session": "Done"
}],
"identifier": [
{
"system": "http://myHospital.org/ChargeItems",
"value": "654321"
}
],
"definitionUri": [
"http://www.kbv.de/tools/ebm/html/01520_2904360860826220813632.html"
],
"status": "billable",
"code": [{
"coding": [
{
"code": "01510",
"display": "Zusatzpauschale für Beobachtung nach diagnostischer Koronarangiografie"
}
]
}]
}
This appears to be a few simple transformations:
First, change
"text": {
to
"text": [{
Second, change
},
"identifier": [
to
}],
"identifier": [
Third, change
"code": {
to
"code": [{
And finally, change
}
}
<EOF>
to
}]
}
<EOF>
However, it might not be as straightforward as it appears, i.e. what if the identifer section isn't always present, or doesn't immediately follow the text section?
Regular expressions are a poor choice for doing this work. It would be much better to read the json file into a native Python data structure, apply your desired changes, then save the json back to the file.
Solution using a multiline regexp search
>>> import re
>>> blocks = re.compile(r'(?ms)(.*)("text": )([{][^{}]+[}])(,.*"status": "billable"[^"]+)("code": )([{][^"]+"coding":[^]]+\]\s+\})')
>>> m = blocks.search(s)
>>> result = ""
>>> for i in range(1,len(m.groups()) + 1):
... if i not in (3,6):
... result += m.group(i)
... else:
... result += "[" + m.group(i) + "]"
...
>>> result += "\n}"

How to deal with the slash and %2F in Python?

Giving the parameters of Interface=['1/1/1', '1/2/3'], tag=11, I need to add the missing interface to json_data[Interface] and json_data[Port] as below. All places except name value used '%2F' as '/'.
Input json:
{
"Interface": {
"1%2F1%2F1": {
"name": "1/1/1",
}
},
"Port": {
"1%2F1%2F1": {
"interfaces": [
"1%2F1%2F1"
],
"name": "1/1/1",
"tag": "10"
}
}
}
Output json should be look like this:
{
"Interface": {
"1%2F1%2F1": {
"name": "1/1/1",
},
"1%2F2%2F3": {
"name": "1/2/3",
}
},
"Port": {
"1%2F1%2F1": {
"interfaces": [
"1%2F1%2F1"
],
"name": "1/1/1",
"tag": "10"
},
"1%2F2%2F3": {
"interfaces": [
"1%2F2%2F3"
],
"name": "1/2/3",
"tag": "11"
}
}
}
I tried with iterate interface list:
for item in interface:
if item is not in json_data["Interface"].keys():
json_data["Interface"][item] = { "name" : item }
But returned in wrong format:
"Interface": {
"2": {
"name": "2"
},
"1": {
"name": "1"
},
"'": {
"name": "'"
},
" ": {
"name": " "
},
",": {
"name": ","
},
"/": {
"name": "/"
},
How to deal with the slash and %2F
Here's a simple way to convert from / to %2F:
'1/1/1'.replace('/', '%2F')
# Results: '1%2F1%2F1'
I'm not sure why you need it in that format, but if it's related to passing it through a URL and you need to escape other characters, you could use:
import urllib
urllib.parse.quote('1/1/1', safe='')
# Results: '1%2F1%2F1'
Your output
It looks like you're accidentally iterating over a string of letters and not a list of interfaces. How are you assigning the interface variable?
Your check for existing interfaces
Your condition if item is not in json_data["Interface"].keys() will not work if item is directly from your input in the format 1/1/1 because all of the keys in json_data["Interface"] use the escaped format.

Categories

Resources