【问题标题】:How to efficiently check if key exists in nested dicts and arrays如何有效地检查嵌套字典和数组中是否存在键
【发布时间】:2021-09-20 16:48:08
【问题描述】:

我一直试图弄清楚如何KISS 从字典中获取价值。

有多种场景如:

  1. 密钥不存在(应返回默认值 {}/[]/"")
  2. 键包含空列表的值(应该返回空列表)
  3. 如果我们试图获取一个值,例如test['objects'][0]['productInfo'][0]['merchPrice']['promoExclusions'][0],如果它已经在 productInfo 失败,它应该立即返回默认值,而不是继续搜索下一个键

我最终做了这样的事情:

test = {
  'pages': {
    'prev': '',
  },
  'objects': [
    {
      'id': 'c362b8f3-1862-4e2d-ba06-d910e0d98e7e',
      'productInfo': [
        {
          'merchProduct': {
            'id': '63912b18-f00f-543f-a5c5-0c6236f63e79',
            'snapshotId': '43cf801e-3689-42c2-ac85-d404e69aba42',

          },
          'merchPrice': {
            'id': '7dd81061-d933-57f6-b233-2a6418ce487d',
            'snapshotId': '268cc5af-8e04-4d64-b19b-02c2770b91fb',
            'discounted': False,
            #Could be | 'promoExclusions': ['TRUE'],
            'promoExclusions': [],
            'resourceType': 'merchPrice',
          }
        }
      ]
    }
  ]
}


if test_print := test['objects'][0]['productInfo'][0]['merchPrice']['promoExclusions'][0]:
   print(test_print)

然而,这会返回一个错误 IndexError: list index out of range,因为该列表不包含任何有意义的值,但我想知道在这种情况下如何为这个粒子问题设置一个默认值。

我的问题是: 如何在不使用大量资源的情况下尽可能简单高效地查找和获取 dict 的值,如果未找到则返回默认值?

【问题讨论】:

标签: python python-3.x dictionary


【解决方案1】:

对于单个dict,您可以使用d.get('key', default),但对于嵌套提取字符串没有简单的快捷方式。你可以用try/except来做到这一点

try:
    test_print = test['objects'][0]['productInfo'][0]['merchPrice']['promoExclusions'][0]
except KeyError:
    test_print = default_value
print(test_print)

【讨论】:

  • 对,有道理:) 我在想什么,或者我没有尝试除原则之外的原因是因为如果我想获得多个密钥。假设大约有 20 个不同的键,代码会很长,其中每个 get key 都需要在 try/except 中覆盖。我的想法是,如果我能做类似if the key is in the json then get the value 的事情,也许?编辑:我并不是说你的方式是错误的,只是告诉我,如果有一种方法,我想让它变得更容易,因为我想尽可能少地保留代码:)
  • 您可以使用stackoverflow.com/questions/14692690/…从键列表中访问嵌套数据,如果找不到键,循环可以返回默认值。
  • 然后,每次我想在嵌套字典中获取键时,我们都会开始查看更多“更重”的 cpu 使用情况来通过 eaceh 循环,不是吗?
  • 正如我所说,测试没有捷径可走。你可以使用if key in dict,但不能使用if nested_keys in nested_dicts_and_arrays
  • 循环开销可以忽略不计。
【解决方案2】:

您是否尝试过使用 try except ? 下面的 sn-p 打印您尝试访问的字典的值,或者在发生异常时打印默认值。

default = 'default {}/[]/""'
try:
    print(test['objects'][0]['productInfo'][0]['merchPrice']['promoExclusions'][0])
except (KeyError, IndexError):
    print(default)

【讨论】:

【解决方案3】:

如何在不使用大量资源的情况下尽可能简单高效地查找和获取 dict 的值,如果未找到则返回默认值?

这个问题的答案是使用collections.defaultdict:

>>> import collections
>>> d = collections.defaultdict(list, {'key1': [1], 'key2': [2]})
>>> d['key1']
[1]
>>> d['key3']
[]

【讨论】:

  • 非常感谢您的回答!我还没有考虑过defeaultdict! :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 2015-11-26
相关资源
最近更新 更多