【问题标题】:How can I get every URL from dictionary in Python?如何从 Python 中的字典中获取每个 URL?
【发布时间】:2021-04-22 05:14:59
【问题描述】:

我有一个代表菜单的 yaml 字符串。在我从中获得字典后,我尝试获取 URL,简单地说是 Parameter 的键 url 以及不是 Parameter 的其他元素的列表的每个第一个元素。

这是我尝试过的

import yaml
import jmespath
import pprint

setting = """
GeneralSetting:
  - Description: General Setting
MenuSetting:
  - Description: Menu Setting
  - Setting:
    - AutoMenu:
      - Description: Register menu
      - HelpText: This is for auto create menu
      - Value:
        - Sample:
          - Parameter:
            - icon: fa fa-birthday-cake
            - Active: Y
          - Sample: [Sample]
          - Sample Account: [SampleAccount]
        - Multi Journal:
          - Parameter:
            - icon: fas fa-book
            - url: MultiJournal
        - Foreign Exchange:
          - Parameter:
            - icon: fa fa-money-bill-alt
            - url: ForeignExchange
        - Loan Contract:
          - Parameter:
            - icon: fa fa-capsules
            - Active: Y
          - Loan Contract: [LoanContract,1]
          - Loan Report:
            - Loan Detail Listing: [LoanDetailListing,1]
            - Loan Application Detail Listing: [ReportR003,1]

"""

toDict = yaml.load(setting, yaml.SafeLoader)

pp = pprint.PrettyPrinter(indent=2)

# ALL
ALL       = jmespath.search('MenuSetting[].Setting[].AutoMenu[].Value[].*[]', toDict)
ParentURL       = jmespath.search('MenuSetting[].Setting[].AutoMenu[].Value[].*[0][].Parameter[].url', toDict)

NotParameter = {key:value for item in ALL for it in item for key,value in it.items() if key != "Parameter"}

# pp.pprint(NotParameter)

# print ('-----')
SubURL = jmespath.search('*[0]', NotParameter)

SubSubURL = jmespath.search('*[].*[][]', NotParameter)

pp.pprint(ParentURL)
print('---')
pp.pprint(SubURL)
print('---')
pp.pprint(SubSubURL)

由此,我只能对 Parameter 下的 url 的父 URL(例如 [MultiJournal,ForeignExchange])做得很好,但对于子和子子却不行。

我只想要 url 的最终结果作为这个列表

[Sample,SampleAccount,MultiJournal,ForeignExchange,LoanContract,LoanDetailListing,Report/R003]

我尝试了几种方法,但仍然无法得到结果?

有什么方法可以让我得到这样的价值清单吗?谢谢

【问题讨论】:

标签: python pyyaml jmespath


【解决方案1】:

虽然我坚信您的 YAML 结构不是您应该拥有的结构(更多关于较低的),但这里将是一个匹配您预期输出的查询:

MenuSetting[].Setting[].AutoMenu[2].[Value[0].[Sample[].Sample, Sample[]."Sample Account"], Value[]."Multi Journal"[].Parameter[1].url, Value[]."Foreign Exchange"[].Parameter[1].url, Value[]."Loan Contract"[]."Loan Contract"[0], Value[]."Loan Contract"[]."Loan Report"[0]."Loan Detail Listing"[0], Value[]."Loan Contract"[]."Loan Report"[1]."Loan Application Detail Listing"[0]][][][][]

基于您的 YAML 的 JSON 等效项:

{
  "GeneralSetting": [
    {
      "Description": "General Setting"
    }
  ],
  "MenuSetting": [
    {
      "Description": "Menu Setting"
    },
    {
      "Setting": [
        {
          "AutoMenu": [
            {
              "Description": "Register menu"
            },
            {
              "HelpText": "This is for auto create menu"
            },
            {
              "Value": [
                {
                  "Sample": [
                    {
                      "Parameter": [
                        {
                          "icon": "fa fa-birthday-cake"
                        },
                        {
                          "Active": "Y"
                        }
                      ]
                    },
                    {
                      "Sample": [
                        "Sample"
                      ]
                    },
                    {
                      "Sample Account": [
                        "SampleAccount"
                      ]
                    }
                  ]
                },
                {
                  "Multi Journal": [
                    {
                      "Parameter": [
                        {
                          "icon": "fas fa-book"
                        },
                        {
                          "url": "MultiJournal"
                        }
                      ]
                    }
                  ]
                },
                {
                  "Foreign Exchange": [
                    {
                      "Parameter": [
                        {
                          "icon": "fa fa-money-bill-alt"
                        },
                        {
                          "url": "ForeignExchange"
                        }
                      ]
                    }
                  ]
                },
                {
                  "Loan Contract": [
                    {
                      "Parameter": [
                        {
                          "icon": "fa fa-capsules"
                        },
                        {
                          "Active": "Y"
                        }
                      ]
                    },
                    {
                      "Loan Contract": [
                        "LoanContract",
                        1
                      ]
                    },
                    {
                      "Loan Report": [
                        {
                          "Loan Detail Listing": [
                            "LoanDetailListing",
                            1
                          ]
                        },
                        {
                          "Loan Application Detail Listing": [
                            "ReportR003",
                            1
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

这个查询给出:

[
  "Sample",
  "SampleAccount",
  "MultiJournal",
  "ForeignExchange",
  "LoanContract",
  "LoanDetailListing",
  "ReportR003"
]

现在我认为您的 YAML 存在很多问题,并且您混淆了 YAML 中的列表和字典。

列表将以破折号开头:

- carrot
- onions
- potatoes

字典是一组键/值对,所有代表父键的属性:

car:
  brand: ferrari
  model: 488
  engine: "3.9 l twin-turbocharged"

当然,您可以有一个字典列表:

- name: duck
  sound: quack
  legs: 2
- name: cow
  sound: moo
  legs: 4

所以在你的 YAML 中,如果我专注于它的顶部,我相信它应该是这样的:

GeneralSetting:
  Description: General Setting
MenuSetting:
  Description: Menu Setting
  Setting:
    AutoMenu:
      Description: Register menu
      HelpText: This is for auto create menu
      Value:
        Sample:
          Parameter:
            icon: fa fa-birthday-cake
            Active: Y
          Sample: Sample
          Sample Account: SampleAccount
        Multi Journal:
          Parameter:
            icon: fas fa-book
            url: MultiJournal
        Foreign Exchange:
          Parameter:
            icon: fa fa-money-bill-alt
            url: ForeignExchange 
# ...

这当然会彻底改变和简化查询,例如,基于此 YAML,生成的 JSON 将是:

{
  "GeneralSetting": {
    "Description": "General Setting"
  },
  "MenuSetting": {
    "Description": "Menu Setting",
    "Setting": {
      "AutoMenu": {
        "Description": "Register menu",
        "HelpText": "This is for auto create menu",
        "Value": {
          "Sample": {
            "Parameter": {
              "icon": "fa fa-birthday-cake",
              "Active": "Y"
            },
            "Sample": "Sample",
            "Sample Account": "SampleAccount"
          },
          "Multi Journal": {
            "Parameter": {
              "icon": "fas fa-book",
              "url": "MultiJournal"
            }
          },
          "Foreign Exchange": {
            "Parameter": {
              "icon": "fa fa-money-bill-alt",
              "url": "ForeignExchange"
            }
          }
        }
      }
    }
  }
}

对第一个元素的查询是:

MenuSetting.Setting.AutoMenu.Value.[Sample.Sample, Sample."Sample Account", *.Parameter.url][]

这将给出预期:

[
  "Sample",
  "SampleAccount",
  "MultiJournal",
  "ForeignExchange"
]

【讨论】:

  • 非常感谢,但是我可以在提到的 YAML 语法中使用通用语法或通配符如 * 或 [] 而不是只适合上面的值,因为我们可以修改、添加/删除除以上项目?非常感谢:)
  • 好吧,如果没有明确定义您的 YAML 结构,这将是简单的猜测。在它的实际状态中,我发现有几个问题阻止您这样做: 1. 有时您的 url 在menu_name[0] 中,其他时候它在menu_name[0].Parameter[0].url 下。 2. 你没有说明元素是如何相互嵌套的。它们可以嵌套多深,嵌套时会发生什么? 3. 如前所述,似乎混淆了列表和字典的结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-13
  • 2020-03-26
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 2017-10-23
相关资源
最近更新 更多