I have a list of "important" checkpoints which are passed by a user:
important_checkpoints = ['checkpoint_1', 'checkpoint_2', 'checkpoint_3',
'checkpoint_4', 'checkpoint_5']
The term "important" means, that from all possible checkpoints ('checkpoint_1', ... ,checkpoint_99) the user can pass, I am only interested in the checkpoints listed in important_checkpoints
.
Additionally I have a dictionary containing the checkpoints which have actually have been used by the users:
user_checkpoints = {"id_1": "checkpoint_11", "id_2": "checkpoint_3", "id_3": "checkpoint_4",
"id_4": "checkpoint_45", "id_5": "checkpoint_68", "id_6": "checkpoint_1",
"id_7": "checkpoint_1"}
Solution to example: Now I want to get a dictionary which tells me which user-ID passed one of the "important" checkpoints:
{"checkpoint_1": [id_6, id_7], "checkpoint_2": [], "checkpoint_3": [id_2], "checkpoint_4": [id_3],
"checkpoint_5": []}
My not finished solution
I was able to find passed important checkpoints (here: ['checkpoint_1', 'checkpoint_3', 'checkpoint_4']
) but I was not able to match the corresponding IDs.
activated_checkpoints_by_user = [] # activated_forms_for_user_concerns
for key in important_checkpoints:
if key in list(user_checkpoints.values()):
activated_checkpoints_by_user.append(key)
>> activated_checkpoints_by_user
>> ['checkpoint_1', 'checkpoint_3', 'checkpoint_4']
CodePudding user response:
You basically want to map the values in the dictionary user_checkpoints back to the keys. In Python there is no direct way to do it but you can itemize the dictionary and use a loop to get the result you want:
result_dict ={}
for imp_checkpoint in important_checkpoints:
result_dict[imp_checkpoint]=[user_id for user_id, checkpoint in user_checkpoints.items() if checkpoint == imp_checkpoint]
CodePudding user response:
If I've properly understood your question, this should solve your problem:
result = {}
for k in important_checkpoints:
result[k] = []
for i,k in user_checkpoints.items():
if k in important_checkpoints:
result[k].append(i)
print(result)
The output is:
{'checkpoint_1': ['id_6', 'id_7'], 'checkpoint_2': [], 'checkpoint_3': ['id_2'], 'checkpoint_4': ['id_3'], 'checkpoint_5': []}
CodePudding user response:
Since you want all important checkpoints present in the result, even if they were never visited, first create a pre-initialised dictionary of the important checkpoints, called activated_important_checkpoints
below. The value for each will be an empty list []
.
Then iterate over the user_checkpoints
and append each userid only if that checkpoint is important. Which you can check with a dictionary key lookup of activated_important_checkpoints
.
Here's an almost english-to-python version of that:
activated_important_checkpoints = {checkpoint: [] for checkpoint in important_checkpoints}
# {'checkpoint_1': [], 'checkpoint_2': [], ..., 'checkpoint_5': []}
for user, checkpoint in user_checkpoints.items():
if checkpoint in activated_important_checkpoints:
activated_important_checkpoints[checkpoint].append(user)
Value of activated_important_checkpoints
after that:
{'checkpoint_1': ['id_6', 'id_7'],
'checkpoint_2': [],
'checkpoint_3': ['id_2'],
'checkpoint_4': ['id_3'],
'checkpoint_5': []}
Notes:
- The initialisation of
activated_checkpoints_by_user
occurs once, and is O(N). - The next loop to go over all the user checkpoints occurs once, and is O(N).
- The dictionary key lookup in
if checkpoint in activated_checkpoints_by_user
is O(1) due to how key lookups work for dictionaries. For lists, it's O(N).