Home > Net >  How can I modify a specific element(which depends on another dictionary) in a list, where the list i
How can I modify a specific element(which depends on another dictionary) in a list, where the list i

Time:06-28

Given 2 dictionaries of:

  1. the students' id and how many points they've got on each problem:
user_probstat_dict = {'106095014': [3, 1, 1], '106095029': [3, 1, 0], '106095033': [3, 1, 0]}
  1. the students' id and the number of problem that they've been cheated:
user_cheatprob_dict = {'106095029': [1, 3], '106095033': [3]}

My aim is to change the score into 0 for those problems that have been cheated, like for the id '106095029', this student's original score:

'106095029': [3, 1, 0]

should be changed into:

'106095029': [0, 1, 0]

Since maybe not all of the students have cheated, the user_cheatprob_dict won't always include all of the student ids.

Here's my code:

for u, c in user_cheatprob_dict.items():
    for ci in c:
        prob_ind = ci - 1 
            user_probstat_dict.update({u:???})

My thought is to first loop over the user_cheatprob_dict, if there's a student that has problems cheated, then take the key (student id = u) and use the update function to replace the value into 0.

The ??? in my code is the part where I don't know how to refer to only the specific value(by the index prob_ind)in the list. I only knew that if I want to change the whole value, I just need to place 0 at the ???part.

Thanks!

CodePudding user response:

You can use dictionary traversal as follows:

user_probstat_dict = {'106095014': [3, 1, 1], '106095029': [3, 1, 0], '106095033': [3, 1, 0]}
user_cheatprob_dict = {'106095029': [1, 3], '106095033': [3]}

for i in list(user_cheatprob_dict.keys()):
    for j in user_cheatprob_dict[i]:
        user_probstat_dict[i][j-1] = 0
print(user_probstat_dict)

Output: Note that the index of user_cheatprob_dict is offset by -1 to get the correct problem index

{'106095014': [3, 1, 1], '106095029': [0, 1, 0], '106095033': [3, 1, 0]}

CodePudding user response:

I have 2 solutions, depending on your needs. Also, those solutions are safe: it won't raise if a student's id is missing in one or another dict, or if a cheated problem's number doesn't correspond to any problem.

1. Recompute your solution
This is the more compact one, but it consumes more memory since it recreates a new dictionary. Use it only on small enough samples. The advantage is that you let your input unchanged.

def recompute(points_dict, cheat_dict):
    """create a new points dict, but doesn't modify the input"""
    return {
        idd: [p * ((i   1) not in cheat_dict.get(idd, [])) for i, p in enumerate(points)]
        for idd, points in points_dict.items()
    }

When multiplied with a number, a boolean corresponds to the value 1 or 0 (respectively for True or False).

2. Replace directly in the input
Less compact, but also less memory consumption. And your input is changed!

def replace(points_dict, cheat_dict):
    """replace the points in the input: input modified"""
    for idd, numbers in cheat_dict.items():
        if idd in points_dict:
            for num in numbers:
                if num <= len(points_dict[idd]):
                    points_dict[idd][num - 1] = 0
  • Related