Есть ли питонический способ обработки древовидных ключей?

Я ищу питоновую идиому, чтобы превратить список ключей и значение в dict с этими вложенными ключами. Например:

dtree(["a", "b", "c"]) = 42 or dtree("a/b/c".split(sep='/')) = 42 

вернет вложенный dict:

 {"a": {"b": {"c": 42}}} 

Это можно использовать для преобразования набора значений с иерархическими ключами в дерево:

 dtree({ "a/b/c": 10, "a/b/d": 20, "a/e": "foo", "a/f": False, "g": 30 }) would result in: { "a": { "b": { "c": 10, "d": 20 }, "e": foo", "f": False }, "g": 30 } 

Я мог бы написать некоторый код FORTRANish для преобразования с использованием грубой силы и нескольких циклов и, возможно, collections.defaultdict , но, похоже, язык с разбиением и объединениями, а фрагменты и понятия должны иметь примитив, который превращает список строк ["a","b","c"] во вложенные ключи dict ["a"]["b"]["c"] . Каков самый короткий способ сделать это без использования eval в строке выражения dict?

2 Solutions collect form web for “Есть ли питонический способ обработки древовидных ключей?”

Я ищу питоновую идиому, чтобы превратить список ключей и значение в dict с этими ключами вложенными.

 reduce(lambda v, k: {k: v}, reversed("a/b/c".split("/")), 42) 

Это можно использовать для преобразования набора значений с иерархическими ключами в дерево

 def hdict(keys, value, sep="/"): return reduce(lambda v, k: {k: v}, reversed(keys.split(sep)), value) def merge_dict(trg, src): for k, v in src.items(): if k in trg: merge_dict(trg[k], v) else: trg[k] = v def hdict_from_dict(src): result = {} for sub_hdict in map(lambda kv: hdict(*kv), src.items()): merge_dict(result, sub_hdict) return result data = { "a/b/c": 10, "a/b/d": 20, "a/e": "foo", "a/f": False, "g": 30 } print(hdict_from_dict(data)) 

Другое общее решение с использованием collections.defaultdict

 import collections def recursive_dict(): return collections.defaultdict(recursive_dict) def dtree(inp): result = recursive_dict() for keys, value in zip(map(lambda s: s.split("/"), inp), inp.values()): reduce(lambda d, k: d[k], keys[:-1], result)[keys[-1]] = value return result import json print(json.dumps(dtree({ "a/b/c": 10, "a/b/d": 20, "a/e": "foo", "a/f": False, "g": 30 }), indent=4)) 

Или просто для усмешек, так как reduce – самая крутая вещь, так как нарезанный хлеб, вы можете сохранить один SLOC, используя его дважды 🙂

 def dmerge(x, y): result = x.copy() k = next(iter(y)) if k in x: result[k] = dmerge(x[k], y[k]) else: result.update(y) return result def hdict(keys, value, sep="/"): return reduce(lambda v, k: {k: v}, reversed(keys.split(sep)), value) def hdict_from_dict(src): return reduce(lambda x, y: dmerge(x, y), [hdict(k, v) for k, v in src.items()]) data = { "a/b/c": 10, "a/b/d": 20, "a/e": "foo", "a/f": False, "g": 30 } print("flat:", data) print("tree:", hdict_from_dict(data)) 
  • Самый эффективный способ хранения 8M + sha256 хэшей
  • Библиотека Python для создания древовидных графиков из вложенных объектов Python (dicts)
  • Python словарь понимания итератор
  • как добавить выбранные файлы из диалогового окна в словарь?
  • Значения словаря Python - Increment
  • Безопасность потоков в словаре Python
  • Python - создать список с начальной загрузкой
  • Добавление в dict с использованием списка ключевых строк в качестве пути
  • Получить ключ dict по максимальному значению
  • Python: подсчет повторяющихся значений словаря
  • Почему я не могу называть hash () по явно хешируемому методу нераскрывающегося экземпляра?
  • Python - лучший язык программирования в мире.