Кортежи минимальных значений, когда значения хранятся в другом словаре - PullRequest
0 голосов
/ 06 мая 2019

Предположим, у меня есть список

[{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},
        }

я написал {k: [min(v, key = lambda x:servicesdict[x]['cost'])]for item in newlist for k, v in item.items()} для получения минимальной стоимости элемента списка в каждом подкатегории списка

Это создает минимальный элемент списка, а не только стоимость

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

Как мне получить соответствующую стоимость? То есть вывод должен быть

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

Ответы [ 3 ]

2 голосов
/ 06 мая 2019
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]}

В основном преобразуйте каждый подсписок в список из [cost, id] пар и возьмите минимум этого. Сравнение по умолчанию для списков сначала сравнит стоимость. Если вместо этого вы создаете [id, cost] пары, вам необходимо указать ключ для сортировки по стоимости.

1 голос
/ 06 мая 2019

Вы можете применить min дважды:

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()}

Выход:

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

Редактировать: если вы хотите, чтобы первый элемент в каждом списке был ключом минимального значенияв servicesdict, тогда можно применять min с ключом`:

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()}

Выход:

{0: [3, 20], 1: [4, 20], 2: [5, 10], 3: [9, 20], 4: [10, 20]}
1 голос
/ 06 мая 2019

Пожалуй, самый простой подход здесь - использовать полученный список:

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

И добавьте соответствующий cost со следующим пониманием словаря:

{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]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...