Как преобразовать строго отсортированный список строк в dict? - PullRequest
2 голосов
/ 19 октября 2011

У меня есть строго отсортированный список строк:

['a',
 'b',
 'b/c',
 'b/d',
 'e',
 'f',
 'f/g',
 'f/h',
 'f/h/i',
 'f/h/i/j']

Этот список похож на представление дерева.Итак, мне нужно преобразовать его в dict:

{'a': {},
 'b': {'c': {},
       'd': {}},
 'e': {},
 'f': {'g': {},
       'h': {'i': {'j': {}}}}}

Как видите, ключи в этом dict - родители, а значения - дети.

UPD: я согласен, что пустоdict лучше, чем Нет

Ответы [ 5 ]

8 голосов
/ 19 октября 2011

Если вы не настаиваете на None в качестве конечного значения, вы можете использовать компактный код

my_dict = lambda: defaultdict(my_dict)
d = my_dict()
for x in my_list:
    reduce(defaultdict.__getitem__, x.split("/"), d)

По общему признанию, это не , что очевидно, что этот кодделает, но это лаконично:)

5 голосов
/ 19 октября 2011
di = {}
for a in arr:
    al = a.split("/")
    d = di
    for elem in al:
        if elem in d:
            d = d[elem]
        else:
            d[elem]={}

print di

Обратите внимание, что элементы не хранятся в алфавитном порядке в словаре!

0 голосов
/ 19 октября 2011

это мое разрешение:

from collections import defaultdict
from pprint import pprint

input = ['a', 'b', 'b/c', 'b/d', 'e', 'f', 'f/g', 'f/h', 'f/h/i', 'f/h/i/j']
result = defaultdict(dict)
for i in input:
    path = i.split('/')
    key = path[0]
    value = {}
    buffer = {key:value}
    for folder in path[1:]:
        value[folder] = {}
        value = value[folder]
    result[key].update(buffer[key])
pprint(dict(result))
0 голосов
/ 19 октября 2011

Надеюсь, это поможет, рекурсивный подход:)

import pprint

l = ['a',
'b',
'b/c',
'b/d',
'e',
'f',
'f/g',
'f/h',
'f/h/i',
'f/h/i/j']

def put(d, elems):
    f = elems[0]
    if len(elems)==1:
        d[f]=None
    else:
        if f not in d or d[f]==None:
            d[f] = {}
        put(d[f], elems[1:])

d = {}
for x in l:
    put(d, x.split('/'))

pprint.pprint(d)
0 голосов
/ 19 октября 2011

Вот моя трещина в этом. Я перевернул путь для оптимизации, потому что pop () намного быстрее, чем pop (0).

def add_branch(root, path):
    branch = path.pop()
    if path:
        if branch not in root or root[branch] is None:
            root[branch] = {}
        add_branch(root[branch], path)
    else:
        root[branch] = None

def totree(strings):
    root = {}
    for string in strings:
        path = string.split("/")
        path.reverse()
        add_branch(root, path)
    return root

Используйте вот так:

my_tree = totree(['a', 'b', 'b/c', 'b/d', 'e', 'f', 'f/g', 'f/h', 
    'f/h/i', 'f/h/i/j'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...