user3206440
user3206440

Reputation: 5059

python check if dict has any nested items

What is the pythonic way of checking if a dict has nested elements

Examples

hasNestedElt({'a': 1, 'b': 2}) #=> False
hasNestedElt({'a': 1, 'b': {'c': 3} }) #=> True
hasNestedElt({'a': 1, 'b': ('c', 3) }) #=> False
hasNestedElt({'a': 1, 'b': ('c', 3, 'x') }) #=> False
hasNestedElt({'a': 1, 'b': ('c', (3, 'x')) }) #=> True
hasNestedElt({'a': 1, 'b': ('c', (3, {'d': 4})) }) #=> True

one way is to iterate through elements in the dict and checking for type like below and reducing the res list. However it becomes unwieldy with nested elements having tuples with varying length.

res = []
for k, v in dct:
  if isinstance(v, (str, int):
    res.append(False)
  elif isinstance(v, tuple) & len(v) == 2:
    if isinstance(v[0], (str,int)) and isinstance(v[1], (str,int)):
      res.append(False)
    else: res.append(True)

Upvotes: 2

Views: 84

Answers (1)

RoadRunner
RoadRunner

Reputation: 26315

As the comments have suggested, you could make use of any() here:

Return True if any element of the iterable is true. If the iterable is empty, return False

What the below code does is iterate the values from the dictionary, if we find a dict return True. If we find a tuple, check if any sub elements are tuple or dict, then return True if we find any. Otherwise return False if we make to the end of the function and no nested elements have been found. This assumes your not handling list or any other type of collection, which is not a problem and can easily be added to the below code.

def hasNestedElt(dic):
    for v in dic.values():
        if isinstance(v, dict):
            return True
        elif isinstance(v, tuple):
            if any(isinstance(x, (dict, tuple)) for x in v):
                return True
    return False

Test cases:

>>> hasNestedElt({'a': 1, 'b': 2}))
False
>>> hasNestedElt({'a': 1, 'b': {'c': 3} })
True
>>> hasNestedElt({'a': 1, 'b': ('c', 3) }) 
False
>>> hasNestedElt({'a': 1, 'b': ('c', 3, 'x') })
False
>>> hasNestedElt({'a': 1, 'b': ('c', (3, 'x')) })
True
>>> hasNestedElt({'a': 1, 'b': ('c', (3, {'d': 4})) })
True

Upvotes: 1

Related Questions