简体   繁体   中英

How to iterate over every keys and values of a nested dictionary

i have created a nested dictionary from the input given in a file. Writing the input of the file below for your reference:-

name1: #(for student 1)

name2, 1

name3, 0

name4, 1 …

name2: #(for student 2)

name1, 0

name3, 0

name4, 0 … and so on for every student.

scenario of the question is, each and every student is conducting a survey yes(1)/no(0) based and noting down the response of every other student. and in the end we have to tell which student have got more yes(1) response.

I have tried to do it by making a nested dictionary from the input from a file but now i'm stuck on how to iterate over every keys and values of nested dictionary and count which student has got maximum yes(1) responses.

The nested dictionary is of the form:- {'name1': {'name2': 1, 'name3': 0, 'name4': 1}, 'name2': {'name1': 0, 'name3': 0, 'name4': 0}}

I'm a beginner and nested dictionary is new to me but i have tried below code

d = {}

with open("C:\\Users\\Administrator\\python\\yearbook.txt") as f:
    for line in f:
        line = line.strip()
        if line.endswith(':'):
            name = line[:-1]
            d[name] = {}
        elif line:
            innername, value = line.split(',')
            d[name][innername] = int(value)


def nested_dict_pairs_iterator(dict_obj):
    ''' This function accepts a nested dictionary as argument
        and iterate over all values of nested dictionaries
    '''
    # Iterate over all key-value pairs of dict argument
    for key, value in dict_obj.items():
        # Check if value is of dict type
        if isinstance(value, dict):
            # If value is dict then iterate over all its values
            for pair in  nested_dict_pairs_iterator(value):
                yield (key, *pair)
        else:
            # If value is not dict type then yield the value
            yield (key, value)
#Loop through all key-value pairs of a nested dictionary
count = 0
for pair in nested_dict_pairs_iterator(d):
    if(pair[2]==1):
        count+=1
print(count)

Maybe the below solution could serve your purpose. Let me know if you have any questions.

def get_results(mydict):
    results = {}
    for key,val in mydict.items():
        for student, vote in mydict[key].items():
            if (vote == 1):
                if key in results.keys():
                    results[key] += 1
                else:
                    results[key] = 1
    return results
          
mydict = {'name1': {'name2': 1, 'name3': 1, 'name4': 1}, 'name2': {'name1': 0, 'name3': 1, 'name4': 0},'name3': {'name1': 0, 'name2': 0, 'name4': 1},'name4': {'name1': 0, 'name3': 1, 'name2': 0}}      
print(get_results(mydict))

output: {'name1': 3, 'name2': 1, 'name3': 1, 'name4': 1}

To do what you want to do, I can advise you to create a dictionary with a key for each student name, and a number that you will increment each time you get a 1

# Loop through all key-value pairs of a nested dictionary
student_note = {}

for pair in nested_dict_pairs_iterator(d):
    if len(pair) == 3:
        student, student2, note = pair
        if student not in student_note:
            student_note[student] = 0
        if note == 1:
            student_note[student] += 1

And with:

d = {
    "name1": {"name2": 1, "name3": 0, "name4": 1},
    "name2": {"name1": 0, "name3": 0, "name4": 0},
}

I get: {'name1': 2, 'name2': 0}

Here's an alternative solution, just sum the values in the inner dict s for each student:

data = {'name1': {'name2': 1, 'name3': 1, 'name4': 1}, 'name2': {'name1': 0, 'name3': 1, 'name4': 0},'name3': {'name1': 0, 'name2': 0, 'name4': 1},'name4': {'name1': 0, 'name3': 1, 'name2': 0}}
count = {student: sum(responses.values()) for student,responses in data.items()}
print(count)

Outputs:

{'name1': 3, 'name2': 1, 'name3': 1, 'name4': 1}

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