Home > Back-end >  Dictionaries and loops in Python 3.x
Dictionaries and loops in Python 3.x

Time:11-06

We have a group grade log:

log = {

    'Alex': [3, 7, 11, 10, 8],

    'Ben': [6, 12, 4, 9, 9],

    'Сarla': [5, 10, 7, 5, 9]}

Output "Best student X, he has the maximum score Y, minimum score Z"

Solution

I have a dictionary, the first thing I decided to do was transform it and replace the values with new ones by hooking the maximum and minimum scores for each student. After that, in a loop I wanted to go through only the maximum scores of each student and find the maximum average and, using it, return the key in the dictionary that corresponds to the meaning. But an error occurs that I cannot figure out. After passing through the loop, the data is converted to int and it is impossible to work with them. What to do?

Code

log = {
    'Alex': [3, 7, 11, 10, 8],
    'Ben': [6, 12, 4, 9, 9],
    'Carla': [5, 10, 7, 5, 9]}

log.update({"Alex":[min(log["Alex"])]   [max(log["Alex"])],
                 "Ben":[min(log["Ben"])]   [max(log["Ben"])],
                 "Carla":[min(log["Carla"])]   [max(log["Carla"])]})

for i,j in log.values():
    print(max(i,j)) 

Output

3 11

4 12

5 10

Here is the problem, int object isn't itarible. I want to find the largest pair, that is max(j), I have to go through, but then how can I return a pair of values at once, and not just the max(j).

CodePudding user response:

This is how one finds the best student:

def by_total_grade(name):
    return sum(grades[name])

best_student = max(grades, key=by_total_grade)

Full example:

grades = {
    "Alex": [3, 7, 11, 10, 8],
    "Ben": [6, 12, 4, 9, 9],
    "Сarla": [5, 10, 7, 5, 9],
}

best_student = max(grades, key=lambda k: sum(grades[k]))
best_grades = grades[best_student]

print(
    f"Best student {best_student}, "
    f"max score {max(best_grades)}, "
    f"min score {min(best_grades)}."
)

Output:

Best student Ben, max score 12, min score 4.

CodePudding user response:

I must admit it is not 100% clear to me want you want to achieve - anyway, this is my try (using the minimum amount of Python notions and mantaining your code as much as possible):

log = {
    'Alex': [3, 7, 11, 10, 8],
    'Ben': [6, 12, 4, 9, 9],
    'Carla': [5, 10, 7, 5, 9]}

for key, vs in log.items():
    log.update({key: [[min(vs)]   [max(vs)]]})

#log.update({"Alex":[min(log["Alex"])]   [max(log["Alex"])],
#            "Ben":[min(log["Ben"])]   [max(log["Ben"])],
#            "Carla":[min(log["Carla"])]   [max(log["Carla"])]})

current_max = -1
best_student = "Unknown"
for name, vs in log.items():  # this retrieves key and value for each entry in the dictionary
    m = max(vs[0]) # why are you comparing the mix with the max of each student? Should this always be j[1]?
    if m > current_max:
        current_max, best_student = m, name

print("Best student is "   best_student   " his top vote is "   str(current_max))

A few comments:

  • It is safer to use a loop to run the log update: if, by any chance, you forget to run the update for 1 student manually, you will incur into troubles. THe loop "makes sure" this does not happen

  • Why, when you run the update of your log dictionary, you update with a list of lists, where the first list always contains the min and the second the max? Can't you update using just a simple list, where the first element is the min, the second the max?

    log.update({key: [min(vs), max(vs)]})
    
  • I don't understand why, in your loop, you check what the max is between 2 numbers (I am referring to m = max(vs[0]), or max(i, j) in your case) where you already know the first is the min and the second is the max. If you apply the change described in the previous point, this simply becomes:

    m = vs[1] 
    
  • Related