简体   繁体   中英

Iterating through a nested dictionary to check if a particular value is all numerical letters

the following is a subset of a really large nested dictionary that I have:

{
 '1': {'Name': 'Katherine Watson',
       'Age': '1',
       'Height': '150'},
 '2': {'Name': 'Emilia Li',
       'Age': '56',
       'Height': '175'},
 '3': {'Name': 'Dorothy Johnson',
       'Age': '29',
       'Height': '162'},
 '4': {'Name': 'Alexandar Knight',
       'Age': '14',
       'Height': '164r'}
}

I'm having trouble figuring out how to write a function that will iterate through the specific key ('Height'), which then returns the corresponding value if it's all numerical numbers or None otherwise. Eg the dictionary with ID'1' should return '150' for the height. But the dictionary with ID'4' should return None for the height.

Here's a code I've written but it only returns '150' instead of iterating through all the IDs and returning '150' '175' '162' 'None'.

data = {
 '1': {'Name': 'Katherine Watson',
       'Age': '1',
       'Height': '150'},
 '2': {'Name': 'Emilia Li',
       'Age': '56',
       'Height': '175'},
 '3': {'Name': 'Dorothy Johnson',
       'Age': '29',
       'Height': '162'},
 '4': {'Name': 'Alexandar Knight',
       'Age': '14',
       'Height': '164r'}
}

def person_height(height):
    for some_id, info in data.items():
        if info['Height'].isnumeric():
            return info['Height']
        else:
            return None

Use isdigit

data = {
 '1': {'Name': 'Katherine Watson',
       'Age': '1',
       'Height': '150'},
 '2': {'Name': 'Emilia Li',
       'Age': '56',
       'Height': '175'},
 '3': {'Name': 'Dorothy Johnson',
       'Age': '29',
       'Height': '162'},
 '4': {'Name': 'Alexandar Knight',
       'Age': '14',
       'Height': '164r'}
}

def person_height(height):
    if height.isdigit():
        return height

for some_id, info in data.items():
    print("\nID:", some_id)
    print("Height:", person_height(info['Height']))

Output:

ID: 1
Height: 150

ID: 2
Height: 175

ID: 3
Height: 162

ID: 4
Height: None

Your code is fine actually but return will break the loop immediately and return the first result only so just turn your return to print() will do the work.

Another way is save the result to a list first and read them later:

data = {
 '1': {'Name': 'Katherine Watson',
       'Age': '1',
       'Height': '150'},
 '2': {'Name': 'Emilia Li',
       'Age': '56',
       'Height': '175'},
 '3': {'Name': 'Dorothy Johnson',
       'Age': '29',
       'Height': '162'},
 '4': {'Name': 'Alexandar Knight',
       'Age': '14',
       'Height': '164r'}
}

def person_height(data):
    height_list = []
    for some_id, info in data.items():
        if info['Height'].isnumeric():
            height_list.append(info['Height'])
        else:
            height_list.append(None)
    return height_list

for height in person_height(data):
    print(height)

Output:

150
175
162
None

You could also do this with a list comprehension .

def get_heights(data):
    return [int(person['Height'])
            if person['Height'].isdigit()
            else None
            for person in data.values()]

print(get_heights(data))

Running it with your sample data outputs:

[150, 175, 162, None]

Since you're not using the IDs, you can use .values() instead of .items() . And in your code, you named the argument height but then refer to data in the function body. This means that it doesn't matter what you supply as the argument; the code only works because it's referring back to the globally defined variable, which happens to have the same name.

I've also converted the heights to integers, even though you didn't specifically request that.

In order to store your results in a "clean" dictionary, you will need as many nested loops as nested dictionaries you have. So:

def check_height(your_dict):
    new_clean_dict = {}
    for a, b in your_dict.items():
        for e, f in b.items():
            if e == 'Height' and f.isdigit():
               new_clean_dict[a] = {'Height': f} 
            else:
               new_clean_dict[a] = {'Height': None}
    return new_clean_dict

This will produce a new dictionary with the same root key and with a value for each key that is a nested dictionary with only the key Height . In order to get the results:

new_clean_dict = check_height(your_dict)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM