dissidia
dissidia

Reputation: 1581

Check and grab latest value of a certain condtion using dictionary

I have created a dictionary in which it stores the information as follows:

dict = {'model_v001': 'In Progress',
 'model_v002': 'In Use',
 'model_v003': 'In Progress',
 'model_v004': 'In Progress',
 'model_v005': 'Approved',
 'model_v006': 'Pending'}

I am trying to achieve the following conditions from the contents in the dictionary:

Using the above example, I should be grabbing model_v005 as it is the latest Approved. So if the model_v004and model_v005 status are reversed, model_v004 will be grabbed instead.

keys = dict.keys()
valid_status = ['Element Approved', 'Element in Pipe']
if dict[keys[0]] in valid_status:
    #Use this version
    print 'Using this version'
else:
    #iterate and check the 'previous' version?

What is the best way to go around this?

Upvotes: 0

Views: 37

Answers (2)

vishes_shell
vishes_shell

Reputation: 23484

As i noted in comment you need to refactor your so called dict variable(i would strongly suggest you to avoid naming variables after build-in names) to something ordered.

One option is to refactor you data into list of tuple objects.

from typing import Optional, List, Tuple

data = [('model_v001', 'In Progress'),
 ('model_v002', 'In Use'),
 ('model_v003', 'In Progress'),
 ('model_v004', 'In Progress'),
 ('model_v005', 'Approved'),
 ('model_v006', 'Pending')]

def return_model(data: List[Tuple[str, str]]) -> Optional[str]:
    latest = {}
    for k, v in data:
        latest[v] = k

    for status in ['Approved', 'In Progress', 'Pending']:
        if status in latest:
            return latest['Approved']
    return None

I used type annotations for easier understanding, which are obviously not obligatory.

What return_model does is it creates dict with latest elements per status(key is status and value is model_name), and then with your rules selects needed one. If no condition is met, then it returns None.

Without type annotations

def return_model(data):
    latest = {}
    for k, v in data:
        latest[v] = k

    for status in ['Approved', 'In Progress', 'Pending']:
        if status in latest:
            return latest['Approved']
    return None

Upvotes: 0

Brett Beatty
Brett Beatty

Reputation: 5963

Assuming that by 'latest' you mean the highest version number, you could do the following:

original = {
    'model_v001': 'In Progress',
    'model_v002': 'In Use',
    'model_v003': 'In Progress',
    'model_v004': 'In Progress',
    'model_v005': 'Approved',
    'model_v006': 'Pending'}

def best(original):
    return max([key for key, value in original.items() if value == 'Approved']
        or [key for key, value in original.items() if value == 'In Progress']
        or [key for key, value in original.items() if value == 'Pending']
        or [None])

assert best(original) == 'model_v005'

It's not the most efficient, but it creates a list of all models with an 'approved' status. If that is empty, it creates a list of models with an 'in progress' status. If that is empty, it creates a list of models with a 'pending' status. If that is empty, it creates a list with only 'None'. Then it gets the max model from whichever list it created last.

Upvotes: 1

Related Questions