0

Based on this Q&A a certain JSON value can be found using print data[u'X'][50][u'Z']

data[u'X'] results in:

{
  "X" : [ {
    "A" : "B",
    ...
  }, {
    ...
  }, {
    "C" : "D",
  } ]
}

Applying the integer method means that every part that is separated by a comma, e.g. "element" : [ { "name" : "value", ... }, needs to be counted until the required piece has been found, in this case number 50.

What if the JSON structure will be changed in the future? Does this mean that the integer should be updated every time?

In my opinion this method is fragile. How to make it more reliable?

Attempts

print data[u'X'][0] results in:

{u'A': u'B', u'C': u'D'}

while

print data[u'X'][u'A']

results in:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    print data[u'beans'][u'modelerType']
TypeError: list indices must be integers, not unicode
3
  • 1
    Based on your sample, print data[u'X'][50][u'Z'] will be a KeyError. What is "the integer method" to which you refer? Do you mean indexing into a list (in which case, it certainly does not need "to be counted until the required piece has been found" - indexing is O(1))? Commented Jan 26, 2015 at 17:30
  • Yes, if you structure changes, your hard-coded path into that structure likely has to change too. You have a route through a structure, so if the structure changes, your route has to change accordingly. You usually don't hardcode the route; you usually pick landmarks instead, but your question is too broad and devoid of detail to give you suitable landmarks to traverse by. Commented Jan 26, 2015 at 17:37
  • @MartijnPieters question has been updated Commented Jan 26, 2015 at 17:55

2 Answers 2

2

There are 2 types of collections in JSON, arrays and objects (see the API for more info)

For example, a list of items:

x = ['a', 'b', 'c', 'd']
x[2] // Returns 'c'

And an object:

x = {"a": 10, "b": 20, "c": 30}
x['b'] // Returns 20

So assuming you use an object to store the data than you won't need an index number at all, just the name of the property. If you use the list, than you will have to store the list index.

It is possible to store an array in an object and vice versa. For example:

x = [1, 2, 3, {"a": 10, "b": 20, "c": [30, 40, 50]}]
x[0] // Returns 1
x[3] // Returns {"a": 10, "b": 20, "c": [30, 40, 50]}
x[3]['a'] // Returns 10
x[3]['c'][2] // Returns 50
Sign up to request clarification or add additional context in comments.

9 Comments

When strings are used it results in TypeError: list indices must be integers, not unicode
@utrecht: note the difference between { and [. With an object (where you can use strings/unicode) you have to use {. With an array you have to use numbers as indices. Within python it's the difference between a list() and a dict() which are also denounced by a [] and {} respectively.
So in this case integers should be used always? It is not possible to make it less fragile by using strings?
If you want to use strings, use objects. If you have no need for strings, use an array. Note that the downside of objects is the inconsistent sort order, so if you need ordering you will have to use an array.
I cannot change the json file. I am trying to get specific value from a jmx page.
|
0

This is probably closer to what you're looking for:

models = ['JvmMetrics', 'MyMetrics']
filtered = filter(ldata['beans'], lambda x: x['modelerType'] in models)

It's unlikely that there's a better way unless you want to build another dict from the JMX response.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.