Projections翻译的话说实话我也不知道翻成什么比较准确,姑且就叫“投影”吧,不过带来的功能确实非常的强大、好用。
首先,我先说下我的理解:
- 通配符
*
- 通配符生成的是一个list列表
- 通配符后面查找的元素都会放到这个list里
一、List and Slice Projections
列表和切片在projections中的应用。
1. 常见的接口数据返回
相信很多接口里返回的数据,在一个列表中嵌套了字典,而且每一个元素都是一个json对象,里面的key-value
都是一样的,那如果你想拿到某一个key下的所有value要如何做呢?
import jmespath dic_1 = { "people": [ {"first": "James", "last": "d"}, {"first": "Jacob", "last": "e"}, {"first": "Jayden", "last": "f"}, {"missing": "different"} ], "foo": {"bar": "baz"} } path = jmespath.search("people[*]", dic_1) print(path) #运行结果 D:\Daily\whatisyeild>python jmespath_demo.py [{'first': 'James', 'last': 'd'}, {'first': 'Jacob', 'last': 'e'}, {'first': 'Jayden', 'last': 'f'}, {'missing': 'different'}]
可以看到people[*]
中的通配符 *
匹配了列表中的所有元素,并且以列表的形式返回。
那么这时候取key是first
的值,只需要people[*].first
。
import jmespath dic_1 = { "people": [ {"first": "James", "last": "d"}, {"first": "Jacob", "last": "e"}, {"first": "Jayden", "last": "f"}, {"missing": "different"} ], "foo": {"bar": "baz"} } path = jmespath.search("people[*].first", dic_1) print(path) #运行结果 D:\Daily\whatisyeild>python jmespath_demo.py ['James', 'Jacob', 'Jayden']
可以看到,查找到的元素同样被放到了通配符创建的列表里,并返回。
同样,你也可以切片:
import jmespath dic_1 = { "people": [ {"first": "James", "last": "d"}, {"first": "Jacob", "last": "e"}, {"first": "Jayden", "last": "f"}, {"missing": "different"} ], "foo": {"bar": "baz"} } path = jmespath.search("people[:2].first", dic_1) print(path) #运行结果 D:\Daily\whatisyeild>python jmespath_demo.py ['James', 'Jacob']
2. 更复杂点的数据返回
比如,在字典的值里再嵌套列表,依然可以被投影到通配符创建的列表里。
import jmespath dic_1 = { "people": [ {"first": "James", "last": "d"}, {"first": "Jacob", "last": "e"}, {"first": "Jayden", "last": "f"}, {"first": [["a","b","c"],2,3,4,5], "last": "g"}, {"missing": "different"} ], "foo": {"bar": "baz"} } path = jmespath.search("people[*].first[0]", dic_1) print(path) #运行结果 D:\Daily\whatisyeild>python jmespath_demo.py [['a', 'b', 'c']]
3. 无效情况
需要注意的是,当通配符右边查找的元素是null的时候,投影到结果列表里这个元素是会被忽略的。
比如,people[*].first[0][10]
下标越界了,所以最后输出的结果就是个空列表[]
。
import jmespath dic_1 = { "people": [ {"first": "James", "last": "d"}, {"first": "Jacob", "last": "e"}, {"first": "Jayden", "last": "f"}, {"first": [["a","b","c"],2,3,4,5], "last": "g"}, {"missing": "different"} ], "foo": {"bar": "baz"} } path = jmespath.search("people[*].first[0][10]", dic_1) print(path) #运行结果: D:\Daily\whatisyeild>python jmespath_demo.py []
另外,列表投影仅对list列表有效。如果值不是列表,则表达式的结果为null。
比如,用列表投影取foo[*]
就不行了,因为 "foo": {"bar": "baz"}
对应的是一个json对象,所以会得到一个null
。
import jmespath dic_1 = { "people": [ {"first": "James", "last": "d"}, {"first": "Jacob", "last": "e"}, {"first": "Jayden", "last": "f"}, {"first": [["a","b","c"],2,3,4,5], "last": "g"}, {"missing": "different"} ], "foo": {"bar": "baz"} } path = jmespath.search("foo[*]", dic_1) print(path) #运行结果 D:\Daily\whatisyeild>python jmespath_demo.py None