投影

投影是JMESPath的关键特性之一。它允许您将表达式应用于元素集合。有五种投影:

  • 列表投影
  • 切片投影
  • 对象投影
  • 展平投影
  • 过滤投影

处理投影需要注意的点

  • 投影评估分为两个步骤。左侧(LHS)创建一个初始值的JSON数组。投影的右侧(RHS)是要为左侧创建的JSON数组中的每个元素投影的表达式。在计算左侧和/或右侧时,每个投影类型的语义略有不同。
  • 如果投射到单个数组元素上的表达式的结果为null,则从收集的结果集中忽略该值。
  • 可以使用管道表达式停止投影(稍后讨论)。
  • 列表投影仅对JSON数组有效。如果值不是列表,则表达式的结果为null。

写法说明

  • []:取列表
  • .:取字典
  • *:遍历每个元素

列表投影

在一个列表中嵌套了字典,而且每一个元素都是一个json对象,它有2个key键,分别是first、last,如果你想拿到first下的所有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[*].first", dic_1)
print(path) # 运行结果
['James', 'Jacob', 'Jayden']

在上面的示例中,people[*]代表people下所有的元素,people[*].first代表people下所有的元素中获取key为first的元素值,结果被收集到一个JSON数组中,并作为表达式的结果返回

虽然people数组中有4个元素,但是最后一个{"missing": "different"}的值为null,并不会将null值添加到收集的结果数组中

 

还有,列表投影仅对列表有效,如果值不是列表,比如是对象,那么表达式的结果为null

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("foo[*]", dic_1)
print(path) # 结果
None

以上代码foo是一个对象,并不是列表,所以这里返回的是None

切片投影

切片投影几乎与列表投影相同,但左侧是评估切片的结果,该切片可能未包括原始列表中的所有元素

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) # 结果
['James', 'Jacob']

这里是先从people数组中取出前二个变为[{"first": "James", "last": "d"},{"first": "Jacob", "last": "e"}],然后再取出字段为first的元素值

对象投影

列表投影是为JSON数组定义的,而对象投影是为JSON对象定义的。可以使用*语法创建对象投影。这将创建JSON对象的值列表,并将投影的右侧投影到值列表上。

import jmespath

dic_1 = {
"ops": {
"functionA": {"numArgs": 2},
"functionB": {"numArgs": 3},
"functionC": {"variadic": True}
}
}
path = jmespath.search("ops.*.numArgs", dic_1)
print(path) # 结果
[2, 3]

ops.*.numArgs中的通配符*我们可以看做一个分界线,分为左边和右边,即左边ops,右边numArgs

第一步,左边初始化了一个可以投影的数组:

evaluate(ops, inputData) -> [{"numArgs": 2}, {"numArgs": 3},
{"variadic": True}]

第二步,右边遍历数组里的每一个元素:

evaluate(numArgs, {numArgs: 2}) -> 2
evaluate(numArgs, {numArgs: 3}) -> 3
evaluate(numArgs, {variadic: true}) -> null

但是因为variadic这个key与 numArgs不匹配,所以返回的是null

而对于null,是不会添加到最终返回的结果数组里的,所以最终结果只有[2, 3]

展平投影

JMESPath表达式中可以使用多个投影。在列表/对象投影的情况下,在投影中创建投影时保留原始文档的结构。

例如,让我们以表达式reservations[*].instances[*].state为例。这个表达式表示顶级键保留有一个数组作为值。对于每个数组元素,投影实例[*].state表达式。在每个列表元素中,有一个实例键,它本身就是一个值,我们为列表中的每个列表元素创建一个子投影。下面是一个例子:

import jmespath

dic_1 = {
"reservations": [
{
"instances": [
{"state": "running"},
{"state": "stopped"}
]
},
{
"instances": [
{"state": "terminated"},
{"state": "running"}
]
}
]
}
path = jmespath.search("reservations[*].instances[*].state", dic_1)
print(path) # 结果
[['running', 'stopped'], ['terminated', 'running']]

此表达式的结果是[[“running”,“stopped”],[“terminated”,“running”]],其实最外层的[] 就是 reservations[]创建的,而内部的每一个实例instances[],也会各自再创建出投影列表,所以结果中最外层的[]里包含了2个子元素[]。

如果我们只需要一个实例所有状态的列表呢?理想情况下,我们希望得到一个结果[“running”,“stopped”,“terminated”,“running”]。在这种情况下,我们不关心实例属于哪个保留,我们只需要一个状态列表。

我们可以使用[]而不是[*]来展平列表,表达式:reservations[].instances[].state

import jmespath

dic_1 = {
"reservations": [
{
"instances": [
{"state": "running"},
{"state": "stopped"}
]
},
{
"instances": [
{"state": "terminated"},
{"state": "running"}
]
}
]
}
path = jmespath.search("reservations[].instances[].state", dic_1)
print(path) # 结果
['running', 'stopped', 'terminated', 'running']

总结:

  • 它将子列表展平到父列表中(不是递归的,只是一个级别)。
  • 它会创建一个投影,因此展平投影右侧的任何内容都会投影到新创建的展平列表中。

    您也可以单独使用[]来展平列表:
import jmespath

dic_1 = [
[0, 1],
2,
[3],
4,
[5, [6, 7]]
]
path = jmespath.search("[]", dic_1)
print(path) # 结果
[0, 1, 2, 3, 4, 5, [6, 7]]

可以看到,列表成功展开,[0, 1, 2, 3, 4, 5, [6, 7]] ,不是递归展开,只是同级,子列表[6, 7] 与列表其他元素同级。

如果我们的表达式改为[][],则得到的结果为[0、1、2、3、4、5、6、7]

import jmespath

dic_1 = [
[0, 1],
2,
[3],
4,
[5, [6, 7]]
]
path = jmespath.search("[][]", dic_1)
print(path) # 结果
[0、1、2、3、4、5、6、7]

jmespath(2)投影Projections的更多相关文章

  1. Hibernate中Criteria的完整用法

    1,CriteriaHibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria .2,De ...

  2. hibernate的Criteria条件查询

    项目中用到了criteria的查询方式,觉得挺好用的,下班后找了一下资料,一边测试,一边在博客上面记录下来 1.初解 快速浏览了资料,大致了解了以下的内容: 1. Hibernate 定义了Crite ...

  3. 【hibernate criteria】hibernate中criteria的完整用法 转

    ---恢复内容开始--- 转自:http://www.360doc.com/content/090313/10/26262_2794855.html 1.Criteria Hibernate 设计了 ...

  4. Hibernate条件查询

    设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装.现在对 Hibernate的Criteria 的用法进行总结:Hibernate 设计了 CriteriaSpecificat ...

  5. Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o

    Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o 1. Criteria,,Criterion ,, 1 <2. 主要的对象黑头配置磊 ...

  6. Scala 并行和并发编程-Futures 和 Promises【翻译】

    官网地址 本文内容 简介 Futures 阻塞 异常 Promises 工具 最近看了<七周七语言:理解多种编程泛型>,介绍了七种语言(四种编程范型)的主要特性:基本语法,集合,并行/并发 ...

  7. Hibernate之Criteria的完整用法

    Criteria的完整用法 QBE (Query By Example) Criteria cri = session.createCriteria(Student.class); cri.add(E ...

  8. Hibernate-Criteria用法

    criteria 英[kraɪˈtɪərɪə] 美[kraɪˈtɪrɪə] Hibernate 设计了 CriteriaSpecification Hibernate 设计了 CriteriaSpec ...

  9. Grails 对象关联映射 (GORM) 一

    转自:http://justjavac.iteye.com/blog/701445 Domain 类是任何商业应用的核心. 他们保存事务处理的状态,也处理预期的行为. 他们通过关联联系在一起, one ...

随机推荐

  1. cut和tr命令的联合使用

    cut的-d选项只能是单个字符,而对于多个连续相同字符分隔的字段,单凭cut命令是达不到想要的效果的,特别是多个连续空格分隔时. 但借助tr -s的压缩重复字符功能,可以将多个连续空格压缩为一个空格, ...

  2. Pandas 常见操作详解

    Pandas 常见操作详解 很多人有误解,总以为Pandas跟熊猫有点关系,跟gui叔创建Python一样觉得Pandas是某某奇葩程序员喜欢熊猫就以此命名,简单介绍一下,Pandas的命名来自于面板 ...

  3. 计算机网络安全 —— 对称加密算法 DES

    一.对称加密算法概念 我们通过计算机网络传输数据时,如果无法防止他人窃听, 可以利用密码学技术将发送的数据变换成对任何不知道如何做逆变换人都不可理解的形式, 从而保证了数据的机密性.这种变换被称为加密 ...

  4. linux GPU上多个buffer间的同步 —— ww_mutex、dma-fence的使用 笔记

    原文链接:https://www.cnblogs.com/yaongtime/p/14111134.html   WW-Mutexes   在GPU中一次Render可能会涉及到对多个buffer的引 ...

  5. 计算机网络安全 —— 非对称加密算法 RSA 和数字签名(二)

    一.非对称加密算法基本概念 在对称密钥系统中,两个参与者要共享同一个秘密密钥.但怎样才能做到这一点呢?一种是事先约定,另一种是用信使来传送.在高度自动化的大型计算机网络中,用信使来传送密钥显然是不合适 ...

  6. Python_1生成器(下)之单线并行--生产着消费者模型

    1 import time 2 def consumer(name): 3 print('%s准备吃包子了!' %name) 4 while True: 5 baozi = yield 6 print ...

  7. P5686 和积和

    写在前面 数学题接触的少,卡了半下午,愣是没想到直接往前缀和上考虑,按元素强推莽了半下午 Description 直接跳转到题目去啊 Solution 记 \(A,B\) 的前缀和序列分别为 \(sA ...

  8. SpringMVC听课笔记(二:SpringMVC的 HelloWorld)

    1.如何建Maven web项目,请看http://how2j.cn/k/maven/maven-eclipse-web-project/1334.html 2.Maven项目,pom文件中的jar包 ...

  9. apache和LAMP架构

    资源池: httpd依赖包:apr 和 apr-util 下载:点击这里 httpd 下载:点击这里 mysql 下载:点击这里 php 下载: 点击这里 本章资源: 点击这里 资源提取码:u2jv ...

  10. (26)Vim 2

    1.Vim 查找文本 /abc 从光标所在位置向前查找字符串 abc /^abc 查找以 abc 为行首的行 /abc$ 查找以 abc 为行尾的行 ?abc 从光标所在为主向后查找字符串 abc n ...