Home > Mobile >  Map elements from list with items from dictionary
Map elements from list with items from dictionary

Time:03-22

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:

  1. The initialisation of activated_checkpoints_by_user occurs once, and is O(N).
  2. The next loop to go over all the user checkpoints occurs once, and is O(N).
  3. 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).
  • Related