Search code examples
pythonpriority-queue

Python: updating priorities in a list of dictionaries


I have the following list of dictionaries:

tasks = [{'priority': 2, 'task': 'math', 'complete_time': 15},
{'priority': 10, 'task': 'french', 'complete_time': 90},
{'priority': 5, 'task': 'geography', 'complete_time': 45},
{'priority': 2, 'task': 'math', 'complete_time': 100}]

I would like to update this list by changing the priorities from zero ongoing so that I get:

[
{'priority':0, 'task':'math', 'complete_time': 15},
{'priority':0, 'task':'math', 'complete_time': 100},
{'priority':1, 'task':'geography', 'complete_time': 45},
{'priority':2, 'task':'french', 'complete_time': 90},
]

I have started by listing the set of all possible priority values:

tasks_set = list({x['priority']:x for x in tasks}.values())

which gives:

 [{'priority': 2, 'task': 'math', 'complete_time': 100},
 {'priority': 10, 'task': 'french', 'complete_time': 90},
 {'priority': 5, 'task': 'geography', 'complete_time': 45}]

but am stuck after this!


Solution

  • This is one simple solution:

    from pprint import pprint
    
    tasks = [
        {'priority': 2, 'task': 'math', 'complete_time': 15},
        {'priority': 10, 'task': 'french', 'complete_time': 90},
        {'priority': 5, 'task': 'geography', 'complete_time': 45},
        {'priority': 2, 'task': 'math', 'complete_time': 100}
    ]
    
    priority_set = list(sorted({task["priority"] for task in tasks}))
    priorities_updater = {}
    for i in range(len(priority_set)):
        priorities_updater[priority_set[i]] = i
    
    for i in range(len(tasks)):
        tasks[i]["priority"] = priorities_updater[tasks[i]["priority"]]
    
    pprint(tasks)
    
    # output
    # [{'complete_time': 15, 'priority': 0, 'task': 'math'},
    # {'complete_time': 90, 'priority': 2, 'task': 'french'},
    # {'complete_time': 45, 'priority': 1, 'task': 'geography'},
    # {'complete_time': 100, 'priority': 0, 'task': 'math'}]
    

    You may observe that the priority attribute in the tasks is no longer the first one in the set, this is normal for Python sets, which are un-ordered (contrary to the lists), and for which the default behavior is then to sort the keys by alphabetical order. Here we first build a set with all the priorities using set comprehension ({task["priority"] for task in tasks}). Then we sort the values for them to be in ascending order. Finally, we convert the set to a list (not really necessary here, but a habit I've taken if the indices of the elements are significant).
    When this is done, we build a dictionary in which the keys are the old priorities, while the values are the new ones.
    Finally, we go through the tasks dictionary and update the priorities.