Search code examples
pythonjsonjmespath

How to get key and value instead of only value when filtering with JMESPath?


Input data:

s = {'111': {'name': 'john', 'exp': '1'}, '222': {'name': 'mia', 'exp': '1'}}

Code:

import jmespath
jmespath.search("(*)[?name=='john']", s)

Output:

[{'name': 'john', 'exp': '1'}]

Output I want:

[{'111': {'name': 'john', 'exp': '1'}}]

Solution

  • Convert the dictionary to the list

    l1 = [{'key': k, 'value': v} for k, v in s.items()]
    

    gives

    [{'key': '111', 'value': {'name': 'john', 'exp': '1'}}, {'key': '222', 'value': {'name': 'mia', 'exp': '1'}}]
    

    Select the values where the attribute name is john

    l2 = jmespath.search('[?value.name == `john`]', l1)
    

    gives

    [{'key': '111', 'value': {'name': 'john', 'exp': '1'}}]
    

    Convert the list back to the dictionary

    s2 = dict([[i['key'], i['value']] for i in l2])
    

    gives the expected result

    {'111': {'name': 'john', 'exp': '1'}}
    

    Example of complete code for testing

    #!/usr/bin/python3
    import jmespath
    
    
    s = {'111': {'name': 'john', 'exp': '1'},
         '222': {'name': 'mia', 'exp': '1'}}
    #    '333': {'name': 'john', 'exp': '1'}}
    l1 = [{'key': k, 'value': v} for k, v in s.items()]
    print(l1)
    l2 = jmespath.search('[?value.name == `john`]', l1)
    print(l2)
    s2 = dict([[i['key'], i['value']] for i in l2])
    print(s2)