Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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'}}]
like image 986
SkruDJ Avatar asked Sep 07 '25 18:09

SkruDJ


2 Answers

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)
like image 123
Vladimir Botka Avatar answered Sep 10 '25 13:09

Vladimir Botka


Since you cannot preserve keys in JMESPath when doing an object projection, and that you will have to resort to a loop to have a JSON structure that will allow you to have your desired output see the other answer, the best will probably be to let JMESPath aside for your use case and achieve it with a list comprehension:

Given:

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

print([
    {key: value} 
    for key, value in s.items() 
    if value['name'] == 'john'
])

This yields the expect:

[{'111': {'name': 'john', 'exp': '1'}}]
like image 37
β.εηοιτ.βε Avatar answered Sep 10 '25 12:09

β.εηοιτ.βε