-3

Using standard json library i have to fetch the value for key in the json string similar to this one, Also the key position is not fixed in the json string and it may be under some multiple json object, so how would i navigate to the entire json string and look for key to fetch corresponding value

{
    "app": {
        "GardenCategory": {
            "label": {
                "Flower": "Rose",
                "Fruits": "Apple"
            }
        },
        "Flowers": {
            "Red_Flowers": "Rose",
            "Thorn_Flowers": "Marigold",
            "beautiful_flower": "sunflower",
        },
        "FruitState": {
            "label": {
                "Sweet Fruit": "Mango",
                "Healthy fruits": "Orange",
                "Liquid fruits": "Water-Melon",
            }
        }
}
min2bro
  • 554
  • 2
  • 9
  • 19
  • Why do you have to develop it? Why not use the existing one? – TigerhawkT3 Jun 16 '15 at 18:03
  • Don't write a parser, use the `json` module. – Steve Jessop Jun 16 '15 at 18:03
  • @TigerhawkT3 Perhaps this is homework to build a JSON parser without importing `json`. Is this the case? – Damian Yerrick Jun 16 '15 at 18:04
  • I'm a newbie not sure how to develop using json module, and my question is to develop a function which takes input parameters as Key and search in the json string...not sure just using key how can i search in the entire json string.. – min2bro Jun 16 '15 at 18:07
  • 1
    If you're a newbie who just wants to parse JSON, creating a parser will be a ton more work than just learning how to use the existing one. Read the [documentation](https://docs.python.org/3.4/library/json.html). – TigerhawkT3 Jun 16 '15 at 18:09
  • I'm not sure of the exact position of key within the json..so how would i navigate thru the entire json string and identify the key and fetch it's corresponding value... – min2bro Jun 16 '15 at 18:13
  • So, once again, do you want/need to write your own parser from scratch, or is it ok to use the standard library? – bereal Jun 16 '15 at 18:19
  • it's ok to use standard library, the only issue I'm facing using the standard library is that how would i navigate entire json string to search for a key within hierarchical json objects and identify the key and fetch corresponding value, since the key position is not fixed and i have to search it in the entire json string.. – min2bro Jun 16 '15 at 18:22
  • You are aware that creating your own parser would (should) create exactly the same object, right? You gain absolutely nothing by trying to make your own parser. Read the documentation on the `json` module and see if it gives you any insights into how to solve your issue. – TigerhawkT3 Jun 16 '15 at 18:24
  • 2
    After you parse this json, it's no longer a string, it's a `dict`. Then the question transforms to "how do I find a key in a nested dict". – bereal Jun 16 '15 at 18:29
  • @bereal correct, this is what i was looking for how to find key in a nested dict, is it possible using standard library to search for the key in nested dict? since everytime the dict will change but keys remains same, so not sure how to use libraries to search for this key everytime in a newly nested dic....help much appreciated – min2bro Jun 16 '15 at 18:33
  • Do you want to find a single value, or them all? What's the expected result for the key `Flowers` (in your example it occurs twice, for the string `Rose` and for a sub-dictionary)? – bereal Jun 16 '15 at 18:41
  • @bereal just a single value I need to search say for example "fruits", I have just updated the json string and now I need fetch the value for "Flower" – min2bro Jun 16 '15 at 18:44
  • `jsondata['app']['GardenCategory']['Flower']` – Tim Jun 16 '15 at 18:53
  • @Tim i have a new json string everytime with same key and value, so need to search in the entire string....this won't work here.. – min2bro Jun 16 '15 at 18:56
  • *i have a new json string everytime **with same key and value,*** because of that, it *will* work – Tim Jun 16 '15 at 18:57
  • the Flower key can be inside some other nested dic, say for example in the new json the Flower key is underneath "Flowers" json object then again i need to write it as jsondata['app']['Flowers']['Flower'] – min2bro Jun 16 '15 at 18:59
  • 1
    http://stackoverflow.com/questions/14962485/finding-a-key-recursively-in-a-dictionary – tsn Jun 16 '15 at 19:01

2 Answers2

1

First of all, your json is not formatted properly. you need to remove the commas after "beautiful_flower": "sunflower", and "Liquid fruits": "Water-Melon", you are also missing a bracket at the end of the string.

The next thing you need to do, if you have it as a string, is turn it into a Dictionary in python. You can do it like this:

import json
a='{"app": {"GardenCategory": {"label": {"Flower": "Rose","Fruits": "Apple"}},"Flowers": {"Red_Flowers": "Rose","Thorn_Flowers": "Marigold","beautiful_flower": "sunflower"},"FruitState": {"label": {"Sweet Fruit": "Mango","Healthy fruits": "Orange","Liquid fruits": "Water-Melon"}}}}'
j=json.loads(a)

you can then try to recursively find the element you need with a method:

def find(element, JSON):
    if element in JSON:
        return JSON[element]
    for key in JSON:
        if isinstance(JSON[key], dict):
            return find(element, JSON[key])

This will look at the first level of keys and check if the key you want is in the first level. if it is it will return that value. If it is not in the first level it will loop through all the keys and run find on all the values that are also dictionaries. it will return the value of the first match it finds. for example:

find('Sweet Fruit', j) will return Mango

find('label', j) will return {'Fruits': 'Apple', 'Flower': 'Rose'}

if what you are looking for is not in the dictionary it will return none

find('foobar', j) will return None

Buzz
  • 1,877
  • 21
  • 25
1

As noted in the comments json.load() will give you a dictionary. You just need to traverse that dictionary, recursively if needed, to find the desired key.

My first draft of such a function is:

def find(adict, key):
    if key in adict.keys():
        return adict[key]
    else:
        for ndict in adict.values():
            return find(ndict, key)

In [466]: adict={'a':{"b":3, "c":{"d":4}}}

In [467]: find(adict,'d')
Out[467]: 4

In [468]: find(adict,'e')
...
AttributeError: 'int' object has no attribute 'keys'

Since a json string can also contain lists, the function should handle those as well.

Correcting your example I get:

In [477]: adict=json.loads(txt)
In [478]: find(adict,'Flower')
Out[478]: u'Rose'

A more robust version:

def find1(adict, key):
    if isinstance(adict, dict):
        if key in adict.keys():
            return adict[key]
        for ndict in adict.values():
            x = find1(ndict, key)
            if x: return x
    else:
        return None
hpaulj
  • 221,503
  • 14
  • 230
  • 353