1

I'm a beginner in Python pulling JSON data consisting of nested objects (dictionaries?). I'm trying to iterate through everything to locate a key all of them share, and select only the objects that have a specific value in that key. I spent days researching and applying and now everything is kind of blurring together in some mix of JS/Python analysis paralysis. This is the general format for the JSON data:

{
    "things":{
        "firstThing":{
            "one":"x",
            "two":"y",
            "three":"z"
        },
        "secondThing":{
            "one":"a",
            "two":"b",
            "three":"c"
        },
        "thirdThing":{
            "one":"x",
            "two":"y",
            "three":"z"
        }
    }
}

In this example I want to isolate the dictionaries where two == y. I'm unsure if I should be using

  1. JSON selection (things.things[i].two)
  2. for loop through things, then things[i] looking for two
  3. k/v when I have 3 sets of keys

Can anyone point me in the right direction ?

Alex
  • 18,484
  • 8
  • 60
  • 80
aaaaaz
  • 13
  • 3
  • Possible duplicate of [Iterate over nested dictionary](https://stackoverflow.com/questions/8335096/iterate-over-nested-dictionary) – quamrana Feb 04 '18 at 17:52

3 Answers3

0

Assuming this is only ever one level deep (things), and you want a 'duplicate' of this dictionary with only the matching child dicts included, then you can do this with a dictionary comprehension:

data = {
    "things":{
        "firstThing":{
            "one":"x",
            "two":"y",
            "three":"z"
        },
        "secondThing":{
            "one":"a",
            "two":"b",
            "three":"c"
        },
        "thirdThing":{
            "one":"x",
            "two":"y",
            "three":"z"
        }
    }
}

print({"things": {k:v for k, v in data['things'].items() if 'two' in v and v['two'] == 'y'}})
deeenes
  • 4,148
  • 5
  • 43
  • 59
match
  • 10,388
  • 3
  • 23
  • 41
0

Since you've tagged this with python I assume you'd prefer a python solution. If you know that your 'two' key (whatever it is) is only present at the level of objects that you want, this might be a nice place for a recursive solution: a generator that takes a dictionary and yields any sub-dictionaries that have the correct key and value. This way you don't have to think too much about the structure of your data. Something like this will work, if you're using at least Python 3.3:

def findSubdictsMatching(target, targetKey, targetValue):
    if not isinstance(target, dict):
        # base case
        return
    # check "in" rather than get() to allow None as target value
    if targetKey in target and targetKey[target] == targetValue:
        yield target
    else:
        for key, value in target.items():
            yield from findSubdictsMatching(value, targetKey, targetValue)
Nathan Vērzemnieks
  • 5,495
  • 1
  • 11
  • 23
0

This code allows You to add objects with "two":"y" to list:

import json
m = '{"things":{"firstThing":{"one":"x","two":"y","three":"z"},"secondThing":{"one":"a","two":"b","three":"c"},"thirdThing":{"one":"x","two":"y","three":"z"}}}'
l = json.loads(m)
y_objects = []
for key in l["things"]:
    l_2 = l["things"][key]
    for key_1 in l_2:
        if key_1 == "two":
            if l_2[key_1] == 'y':
                y_objects.append(l_2)

print(y_objects)

Console:

[{'one': 'x', 'two': 'y', 'three': 'z'}, {'one': 'x', 'two': 'y', 'three': 'z'}]
Elefanobi
  • 19
  • 1
  • 5