Python - ключ максимального значения во вложенном dict, обобщение - PullRequest
0 голосов
/ 31 августа 2018

Хотелось бы узнать, как мы можем вернуть значение ключа вложенных диктов. Случай dict of dict (case 1) уже был дан ответ в другом месте, но мне не удается обобщить

Случай 1: диктат диктата

dict = {'key1': {'subkey1': value11, 'subkey2': value12, ...}
        'key2': {'subkey1': value21, 'subkey2': value22, ...}
        ...}

Чтобы получить ключ с максимальным значением 'subkey1', я бы сделал:

max(dict, key=lambda x: dict[x].get('subkey1'))

Дело 2:

dict = {'key1': 
         {'subkey1': 
           {'subsubkey1': value111, 'subsubkey2': value112, ...}}
        'key2': 
          {'subkey2': 
            {'subsubkey1': value211, 'subsubkey2': value212, ...}}}
        ...}

Итак, мои вопросы:

  • Как мы можем обобщить формулу case1? если я хочу 'ключ' максимального 'sububkey'?
  • С точки зрения производительности, может ли другое решение быть более эффективным, чем формула из 1 строки?

Спасибо за вашу помощь и вклад

1 Ответ

0 голосов
/ 01 сентября 2018

Этот ответ предполагает, что вы знаете путь к вложенному ключу. Тогда один из возможных вариантов случая 2:

((d.get(key)).get(subkey1)).get(subsubkey1)

Вы хотите применить функцию get кумулятивным образом, обратите внимание, что get можно заменить оператором [], поэтому приведенную выше строку также можно увидеть следующим образом:

((d[key])[subkey1])[subsubkey1]

Это то, что функция уменьшает делает из документации:

применить функцию двух аргументов кумулятивно к элементам последовательности, слева направо, чтобы уменьшить последовательность до одного значения. Например, Reduce (лямбда x, y: x + y, [1, 2, 3, 4, 5]) вычисляет ((((1 + 2) +3) +4) +5). Левый аргумент, x, является накопленным значением и правильный аргумент y - это значение обновления последовательности.

Таким образом, вы можете вкладывать свои звонки следующим образом:

from functools import reduce

d = {'key1': {'subkey1': {'subsubkey1': 1, 'subsubkey2': 2}},
     'key2': {'subkey1': {'subsubkey1': 2, 'subsubkey2': 3}}}


def value(first_key, di=None, path=None):
    lst = [di, first_key] + path
    return reduce(lambda x, y: x[y], lst)

p = ['subkey1', 'subsubkey1']

print(max(d, key=lambda k: value(k, d, p)))

выход

key2

Обобщение key= происходит из функции value. В основном функции получают ключ верхнего уровня, словарь и пути ключей, а затем с помощью метода Reduce кумулятивно применяется вызов.

UPDATE

В более общем виде, если у вас есть разные пути к 'sub...subkey' для каждой из верхних клавиш ['key1', 'key2', ...], вы можете использовать словарь путей для каждой клавиши следующим образом:

d = {'key1': {'subkey1': {'subsubkey1': 1, 'subsubkey2': 2}},
     'key2': {'subkey2': {'subsubkey1': 2, 'subsubkey2': 3}}}


paths = {
    'key1': ['subkey1', 'subsubkey1'],
    'key2': ['subkey2', 'subsubkey1']
}

print(max(d, key=lambda k: value(k, d, paths[k])))

выход

key2

Обратите внимание, что функция value остается неизменной, только путь для каждой клавиши различен. Также это решение дает вам дополнительные значения разной длины пути для каждой верхней клавиши.

...