-1

How can i check if 'Anna' exists in the dictionary? challenge seems to be accessing the value in the list:

data = {"Pam": {"Job":"Pilot", 
              "YOB": "1986", 
              "Children": ["Greg", "Anna","Sima"]}, 
        "Joe": {"Job":"Engineer", 
              "YOB": "1987"}}
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
MSH
  • 3
  • 1
  • 2
  • 3
    Are you checking specifically if Anna is one of Pam's children, if she is anyones child, or if that name appears anywhere in the dictionary? – Patrick Haugh Apr 29 '18 at 18:41
  • This question has been answered in detail at the below link: https://stackoverflow.com/questions/43491287/elegant-way-to-check-if-a-nested-key-exists-in-a-python-dict?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – Anshul Prakash Apr 29 '18 at 18:43
  • 1
    @AnshulPrakash That question covers looking for keys in nested dicts, but not _values_. – PM 2Ring Apr 29 '18 at 18:46
  • I don't know what you really want but the challenge is actually easy to solve, `"Anna" in ["Greg", "Anna","Sima"]` will return `True`, `"Anna" in ["Greg", "Mary","Sima"]` will return `False`. – Stop harming Monica Apr 29 '18 at 18:49

2 Answers2

2

If your dictionary is as above, and you simply want to test if "Anna" is in the "Children" list of the "Pam" sub-dictionary, you can simply do:

print("Anna" in data["Pam"]["Children"])

but I assume you actually want something more general. ;)

Here's a recursive function that will check an object consisting of nested dictionaries and lists, looking for a given value. The outer object can be a dict or a list, so it's suitable for handling objects created from JSON. Note that it ignores dict keys, it only looks at values. It will recurse as deeply as it needs to, to find a matching value, but it will stop searching as soon as it finds a match.

def has_value(obj, val):
    if isinstance(obj, dict):
        values = obj.values()
    elif isinstance(obj, list):
        values = obj
    if val in values:
        return True
    for v in values:
        if isinstance(v, (dict, list)) and has_value(v, val):
            return True
    return False

# Test

data = {
    "Pam": {
        "Job": "Pilot",
        "YOB": "1986",
        "Children": ["Greg", "Anna", "Sima"]
    },
    "Joe": {
        "Job": "Engineer",
        "YOB": "1987"
    }
}

vals = ("Pam", "Pilot", "1986", "1987", "1988", "YOB", "Greg", 
    "Anna", "Sima", "Engineer", "Doctor")

for v in vals:
    print(v, has_value(data, v))

output

Pam False
Pilot True
1986 True
1987 True
1988 False
YOB False
Greg True
Anna True
Sima True
Engineer True
Doctor False

The obj you pass to has_value must be a dict or a list, otherwise it will fail with

UnboundLocalError: local variable 'values' referenced before assignment
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
1

You can use any with a list comprehension to check if 'Anna' exists as either a key in the dictionary or appears as an element in a subdictionary:

data = {"Pam": {"Job":"Pilot", 
          "YOB": "1986", 
          "Children": ["Greg", "Anna","Sima"]}, 
    "Joe": {"Job":"Engineer", 
          "YOB": "1987"}}
if any(a == 'Anna' or 'Anna' in b.get('children', []) for a, b in data.items()):
   pass
Ajax1234
  • 69,937
  • 8
  • 61
  • 102