kauray
kauray

Reputation: 719

Minimum Value Tuples when Values are stored in another dictionary

Suppose I have a list

[{0: [0, 1, 2, 3], 1: [4]}, {2: [5, 6, 7, 8], 3: [9]}, {4: [10, 11, 12]}]

and another dictionary

    servicesdict = { 0 : {'cost' : 30},
        1 : {'cost' : 50},
        2 : {'cost' : 70},
        3 : {'cost' : 20},
        4 : {'cost' : 20},

        5 : {'cost' : 10},
        6 : {'cost' : 20},
        7 : {'cost' : 50},
        8 : {'cost' : 70},
        9 : {'cost' : 20},

        10 : {'cost' : 20},
        11 : {'cost' : 20},
        12 : {'cost' : 40},
        }

I wrote {k: [min(v, key = lambda x:servicesdict[x]['cost'])]for item in newlist for k, v in item.items()}to get the minimum cost of the list element in each subdictionary of the list

This produces the minimum list element not just the cost

{0: [0], 1: [4], 2: [5], 3: [9], 4: [10]}

How do I get the corresponding cost as well? That is, the output should be

{0: [0, 20], 1: [4, 20], 2: [5, 10], 3: [9, 20], 4: [10, 20]}

Upvotes: 0

Views: 42

Answers (3)

Ajax1234
Ajax1234

Reputation: 71461

You can apply min twice:

d = [{0: [0, 1, 2, 3], 1: [4]}, {2: [5, 6, 7, 8], 3: [9]}, {4: [10, 11, 12]}]
servicesdict = {0: {'cost': 30}, 1: {'cost': 50}, 2: {'cost': 70}, 3: {'cost': 20}, 4: {'cost': 20}, 5: {'cost': 10}, 6: {'cost': 20}, 7: {'cost': 50}, 8: {'cost': 70}, 9: {'cost': 20}, 10: {'cost': 20}, 11: {'cost': 20}, 12: {'cost': 40}}
result = {a:[min(b), min(servicesdict[i]['cost'] for i in b)] for c in d for a, b in c.items()}

Output:

{0: [0, 20], 1: [4, 20], 2: [5, 10], 3: [9, 20], 4: [10, 20]}

Edit: if you want the first element in each list to be the key of the minimum value in servicesdict, then min with key` can be applied:

result = {a:[min(b, key=lambda x:servicesdict[x]['cost']), min(servicesdict[i]['cost'] for i in b)] for c in d for a, b in c.items()}

Output:

{0: [3, 20], 1: [4, 20], 2: [5, 10], 3: [9, 20], 4: [10, 20]}

Upvotes: 1

yatu
yatu

Reputation: 88276

Perhaps the simplest approach here is to use the obtained list:

d = {k: [min(v, key = lambda x:servicesdict[x]['cost'])] for item in newlist 
        for k, v in item.items()}

And add the corresponding cost with the bellow dictionary comprehension:

{k: [*v, servicesdict[v[0]]['cost']] for k,v in d.items()}
# {0: [3, 20], 1: [4, 20], 2: [5, 10], 3: [9, 20], 4: [10, 20]}

Upvotes: 1

Alex Hall
Alex Hall

Reputation: 36043

servicesdict = {
    0: {'cost': 30},
    1: {'cost': 50},
    2: {'cost': 70},
    3: {'cost': 20},
    4: {'cost': 20},

    5: {'cost': 10},
    6: {'cost': 20},
    7: {'cost': 50},
    8: {'cost': 70},
    9: {'cost': 20},

    10: {'cost': 20},
    11: {'cost': 20},
    12: {'cost': 40},
}

newlist = [{0: [0, 1, 2, 3], 1: [4]}, {2: [5, 6, 7, 8], 3: [9]}, {4: [10, 11, 12]}]
mins = {
    k: min([[servicesdict[x]['cost'], x] for x in sublist])
    for dct in newlist
    for k, sublist in dct.items()
}

print(mins)
# {0: [20, 3], 1: [20, 4], 2: [10, 5], 3: [20, 9], 4: [20, 10]}

Basically convert each sublist to a list of [cost, id] pairs and take the min of that. The default comparison for lists will compare the cost first. If you make [id, cost] pairs instead then you need to provide a key to sort by cost.

Upvotes: 2

Related Questions