Reputation: 817
I wrote this little script to extract a specific JSON field passed in from command line. It works and all but it seems inefficient. Any suggestion on any improvement?
jsonx.py name jdoe.json will return "John Doe" jsonx.py rec.course jdoe.json will return "Java"
#!/usr/bin/env python
import sys
import re
import json
def main():
sys.tracebacklimit = 0
argc = len(sys.argv)
if argc == 2:
field = sys.argv[1]
infile = sys.stdin
elif argc == 3:
field = sys.argv[1]
infile = open(sys.argv[2], 'rb')
else:
raise SystemExit(sys.argv[0] + " <json-field> [ <json-file> ]")
with infile:
try:
obj = json.load(infile)
except(ValueError, e):
raise SystemExit(e)
for f in [f for f in re.split("[\.\[\]]", field) if f != '']:
try:
if f.isdigit():
obj = obj[int(f)]
else:
obj = obj[f]
except(ValueError, e):
raise SystemExit(e)
print(obj)
if __name__ == '__main__':
main()
Sample json file:
{
"name": "John Doe",
"rec": {
"id": 1,
"course": "Java"
}
}
Upvotes: 0
Views: 83
Reputation: 817
I added the array handling:
def get_dict(x, field):
fields = [f for f in re.split("[\.\[\]]", field) if f != '']
fields = [(int(i) if i.isdigit() else i) for i in fields]
return reduce(operator.getitem, fields, x)
Upvotes: 0
Reputation: 1173
You could use reduce()
and operator
like this:
x = {"name": "John Doe", "rec": {"id": 1, "course": "Java"}}
from functools import reduce
import operator
def get_dict(mydict, list_attr):
return reduce(operator.getitem, list_attr, mydict)
Try it out:
>>> get_dict(x, ['rec', 'course'])
Java
>>> get_dict(x, ['name'])
John Doe
Upvotes: 1