为了账号安全,请及时绑定邮箱和手机立即绑定

如果使用 JMESPath 选择另一个 JSON 密钥,则选择第一个 JSON 密钥的最佳方法是

如果使用 JMESPath 选择另一个 JSON 密钥,则选择第一个 JSON 密钥的最佳方法是

一只萌萌小番薯 2022-09-13 19:14:39
例如,有一些包含一些产品数据的 JSON:{  "sku": 123,  "product": {    "name": "Some name",    "images": {      "normalImage": "http://somelink.com/1.jpg",      "bigImage": "http://somelink.com/1b.jpg"    }  }}我想选择图像链接,但仅存在于某些产品中,因此有时我需要选择。bigImagenormalImage显而易见的解决方案是这样的:jmespath.search('product.images.bigImage') or jmespath.search('product.images.normalImage')但我觉得可以做得更好。如何使用 JMESPath 语法以最佳方式执行此操作?
查看完整描述

2 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

以下仅使用 JMESPath 语法的情况如何?

product.images.[bigImage, normalImage][?@]|[0]

我们的想法是,我们按照偏好顺序制作一个要使用的所有图像的数组,过滤掉丢失的图像,然后选择剩余数组中的第一个项目。

警告 - 这不会区分缺失值和(或其他“错误”值,例如空字符串),因此,如果这对您的特定情况很重要,则可能需要对其进行一些调整。null


查看完整回答
反对 回复 2022-09-13
?
胡说叔叔

TA贡献1804条经验 获得超8个赞

您可以创建一个类来执行此操作,类似于 GitHub 页面中给出的示例。CustomFunctions


from jmespath import search

from jmespath import functions

from jmespath import Options


from json import loads


class CustomFunctions(functions.Functions):


    # Method that selects 'bigImage' key value if it exists

    # Otherwise return 'normalImage' value

    # dict.get() is perfect for this, since it returns a default value if a key doesn't exist

    # Use type 'object' since thats the equivalant type to a Python dictionary in JSON

    # Make sure to decorate function signature as well to indicate types

    # Make sure to also put _func_ before your function name

    @functions.signature({'types': ['object']})

    def _func_choose_key(self, d):

        return d.get('bigImage', d['normalImage'])


if __name__ == "__main__":


    # Get custom function options

    options = Options(custom_functions=CustomFunctions())


    # Test method which runs JMESPath query with custom function

    def test(json):

        json_dict = loads(json)

        return search('product.images | choose_key(@)', json_dict, options=options)



    # TEST 1 - bigImage key exists

    json1 = """{

        "sku": 123,

        "product": {

            "name": "Some name",

            "images": {

                "normalImage": "http://somelink.com/1.jpg",

                "bigImage": "http://somelink.com/1b.jpg"

            }

        }

    }"""


    print("Test1: %s" % test(json1))



    # TEST 2 - bigImage key doesn't exist

    json2 = """{

        "sku": 123,

        "product": {

            "name": "Some name",

            "images": {

                "normalImage": "http://somelink.com/1.jpg"

            }

        }

    }"""



    print("Test2: %s" % test(json2))

这将打印出以下结果:


Test1: http://somelink.com/1b.jpg  # When bigImage key exists

Test2: http://somelink.com/1.jpg   # When bigImage key doesn't exist

如果JMESPath变得太复杂,我们总是可以使用旧的标准字典方法:


def test2(json):

    json_dict = loads(json)

    images = json_dict["product"]["images"]

    return images.get("bigImage", images["normalImage"])


# TEST 1 - bigImage key exists

json1 = """{

    "sku": 123,

    "product": {

        "name": "Some name",

        "images": {

            "normalImage": "http://somelink.com/1.jpg",

            "bigImage": "http://somelink.com/1b.jpg"

        }

    }

}"""


print("Test1: %s" % test2(json1))



# TEST 2 - bigImage key doesn't exist

json2 = """{

    "sku": 123,

    "product": {

        "name": "Some name",

        "images": {

            "normalImage": "http://somelink.com/1.jpg"

        }

    }

}"""



print("Test2: %s" % test2(json2))

这也打印相同的结果:


Test1: http://somelink.com/1b.jpg  # When bigImage key exists

Test2: http://somelink.com/1.jpg   # When bigImage key doesn't exist


查看完整回答
反对 回复 2022-09-13
  • 2 回答
  • 0 关注
  • 65 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号