1

I need to get a value from json file by index (not by key)

Here is my json file

{
    "db": {
        "vendor": {
            "product": {
                "fruits": {
                    "price": {
                        "dollars": [
                            10,
                            2
                        ],
                        "euros": [
                            11,
                            1.9
                        ],
                        "pesos": [
                            16,
                            15
                        ]
                    }
                },
                "vegatables": {
                    "price": {
                        "dollars": {
                            "0": 8,
                            "1": 2
                        },
                        "euros": {
                            "0": 10,
                            "1": 1.5
                        },
                        "pesos": {
                            "0": 15,
                            "1": 12
                        }
                    }
                }
            }
        }
    }
}

My goal - get values in dollars, euros and pesos for all "products" (in this json file it is fruits and vegatables only)

My code:

import json

path_to_file = "C:\\Users\\admin\\Documents\\kolos\\data\\vegs.json";

with open(path_to_file) as data_file:
    data = json.load(data_file)

lenght_of_products = (len(data["db"]["vendor"]["product"]))

for x in range(lenght_of_back):
print(data["db"]["vendor"]["product"][x]["price"]["dollars"])

And I got

Traceback (most recent call last):
  File "C:\\Users\\admin\\Documents\\kolos\\data\\vegs.json", line 12, in <module>
    print(data["db"]["vendor"]["product"][x]["price"]["dollars"])
KeyError: 0

The problem is in X variable. If I try without it, for example code below, it works.

print(data["db"]["vendor"]["product"]["fruits"]["price"]["dollars"][0])

P.S

In my another program I use the similar code and it works great

   ...
    for x in range(lenght_of_leagues):
        print(data["leagues"][x]["id"])
    ...
ClydeTheGhost
  • 1,473
  • 2
  • 17
  • 31
Alex Lian
  • 47
  • 1
  • 1
  • 7
  • Possible duplicate of [Python access to first element in dictionary](http://stackoverflow.com/questions/3097866/python-access-to-first-element-in-dictionary) – Martin Valgur Aug 19 '16 at 10:35
  • Your KeyError is probably due to trying to index an number (because the contents of 'spinach' is a number). And 'first item' is not well-defined in JSON. You could say `next(iter(data["d"]["items"]["vegatables"]))` to get some key in vegetables. – Tim Fuchs Aug 19 '16 at 10:37
  • 3
    "And i get the error 'KeyError: 1'" Not with that code, you don't. Please produce a [SSCCE](http://sscce.org/). – Karl Knechtel Aug 19 '16 at 10:48
  • Please share complete input string and expected output. Note that dict don't have any ordering but while loading the JSON you can preserve the ordering by using `collections.OrderedDict` as [`object_pairs_hook`](https://docs.python.org/3.5/library/json.html#json.JSONDecoder). – Ashwini Chaudhary Aug 19 '16 at 10:51
  • Ok, I edit my message fully, please see again. – Alex Lian Aug 19 '16 at 12:34

2 Answers2

2

Here's a version that should work (depending on what you expect it to do):

  • I changed the dict() to an OrderedDict() to preserve the original ordering

  • I added .values() to the dictionary which is being indexed into. This method returns a list of all dictionaries which can then be indexed into

Here's the code:

import json
from collections import OrderedDict

path_to_file = "test.json";

with open(path_to_file) as data_file:
    data = OrderedDict(json.load(data_file))

length = (len(data["db"]["vendor"]["product"]))

for x in range(length):
    print(data["db"]["vendor"]["product"].values()[x]["price"]["dollars"])

Output is:

{u'1': 2, u'0': 8}
[10, 2]

The reason the output is different is that your fruits and vegetables are stored differently (one is a list and the other is a dictionary). You'll have to make them the same if you want to be able to iterate over them in a similar fashion.

ClydeTheGhost
  • 1,473
  • 2
  • 17
  • 31
  • Hm...but I got the following error "line 12, in print(data["db"]["vendor"]["product"].values()[x]["price"]["dollars"]) TypeError: 'dict_values' object does not support indexing" – Alex Lian Aug 19 '16 at 13:13
  • Not sure if it makes a difference but I used Python 2.7 – ClydeTheGhost Aug 19 '16 at 15:52
0

I think the input string is wrong.

{
    "d": {
        "items": {
             "vegatables": {
                           "spinach": 120,12,23,3445
                           }
                 }
          }
}

JSON format doesn't has the the following input it must be changed to

{
    "d": {
        "items": {
             "vegatables": {
                           "spinach": [120,12,23,3445]
                           }
                 }
          }
}

Then the following command will work fine

print(data["d"]["items"]["vegatables"]["spinach"][0])
Anand Tripathi
  • 14,556
  • 1
  • 47
  • 52
  • Why did you add a list of numbers to the spinach key? – OneCricketeer Aug 19 '16 at 11:22
  • I just converted that input json file because the input json file format is incorrect and it will be corrected by this way in my opinion. – Anand Tripathi Aug 19 '16 at 11:41
  • I understand that your solution would make that line of code work, but think about the data - why would spinach be a list of numbers? It makes more sense that there is a total quantity of "120 spinach" – OneCricketeer Aug 19 '16 at 11:43
  • Then can you provide me the correct input json file? – Anand Tripathi Aug 19 '16 at 11:52
  • How would I be able to do that? I didn't ask the question in the post. You should assume that the JSON in the question is correct – OneCricketeer Aug 19 '16 at 11:56
  • I assume but how could i assume what is after that comma,it can be another key-value or it can be only value that's why Alex is printing with index number so by I am only saying that json file cannot have parameters with comma or tuple it should list or dictionary so i am guessing it may be the input file is not a json file(Incorrect json file) or Alex has to explain his question a little bit cause you also dont know the inpput json file – Anand Tripathi Aug 19 '16 at 12:00
  • It's probably more vegetable items after the comma – OneCricketeer Aug 19 '16 at 12:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/121345/discussion-between-anand-tripathi-and-cricket-007). – Anand Tripathi Aug 19 '16 at 12:06