Home > Software design >  How to efficiently check if key exists in nested dicts and arrays
How to efficiently check if key exists in nested dicts and arrays

Time:09-21

I have been trying to figure out how to KISS when it comes to get value from a dict.

There is various scenarios such as:

  1. The key does not exists (Should return default {}/[]/"")
  2. The key contains a value of empty list (Should then return empty list)
  3. If we trying to grab a value e.g. test['objects'][0]['productInfo'][0]['merchPrice']['promoExclusions'][0] and if it already fails at productInfo, it should imminently return the default instead of continuing searching for the next key

I have ended up doing something like this:

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)

This however returns an error IndexError: list index out of range due to the list does not contain any value which make sense but I wonder how I could in that case set a default value for this particle problem.

My question is: How can I keep it as simple as possible and efficiently to find and get the value of a dict without needing to use alot of resources and if its not found then return a default value?

CodePudding user response:

For a single dict you could use d.get('key', default), but there's no simple shortcut for a string of nested extractions. You can do it with try/except

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

CodePudding user response:

Have you tried using try except ? The snippet below prints the value of the dictionary that you are trying to access, or prints default in the event of an exception.

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

CodePudding user response:

How can I keep it as simple as possible and efficiently to find and get the value of a dict without needing to use alot of resources and if its not found then return a default value?

The answer to this question is to use collections.defaultdict:

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

  • Related