2015-03-03 3 views
3

У меня есть список следующим образомСписок вложенным словаря в Python

['item1', 'item2', 'item3', 'item4'] 

Я хочу, чтобы построить словарь из приведенного выше списка следующим

{ 
    "item1": { 
     "item2": { 
      "item3": "item4" 
     } 
    } 
} 

Количество элементов в списке является динамическим , Словарь будет вложенным словарем, пока не достигнет последнего элемента списка. Есть ли способ в python для этого?

+0

Связанный: [питон доступа к вложенным словарные элементы через список ключей] (http://stackoverflow.com/q/14692690) –

ответ

9

Простой один вкладыш:

a = ['item1', 'item2', 'item3','item4'] 
print reduce(lambda x, y: {y: x}, reversed(a)) 

Для лучшего понимания приведенного выше кода может быть расширен:

def nest_me(x, y): 
    """ 
    Take two arguments and return a one element dict with first 
    argument as a value and second as a key 
    """ 
    return {y: x} 

a = ['item1', 'item2', 'item3','item4'] 
rev_a = reversed(a) # ['item4', 'item3', 'item2','item1'] 
print reduce(
    nest_me, # Function applied until the list is reduced to one element list 
    rev_a # Iterable to be reduced 
) 
# {'item1': {'item2': {'item3': 'item4'}}} 
+1

Огромный большой палец вверх :) – volcano

+0

Ничего себе, красиво! –

4

Использование рекурсии:

In [10]: src = ['item1', 'item2', 'item3','item4'] 

In [11]: def list2dict(src_list): 
    if len(src_list) > 1: 
     return {src_list[0] : list2dict(src_list[1:])} 
    else: 
     return src_list[0] 
    ....:  

In [12]: 

In [12]: list2dict(src) 
Out[12]: {'item1': {'item2': {'item3': 'item4'}}} 
+0

Жаль, что @thefourtheye удалили его nswer - в то время как это решение более естественно, я должен сказать, что его преимущество заключалось в устранении нарезки над головой - это сложность O (n!), его O (n) – volcano

3

Использование reduce() function для доступа и установки элементов:

try: 
    # Python 3 moved reduce to the functools module 
    from functools import reduce 
except ImportError: 
    # Python 2 reduce is a built-in 
    pass 

def get_target(d, keys): 
    return reduce(lambda d, k: d.setdefault(k, {}), keys, d) 

def set_target(d, keys, value): 
    parent = get_target(d, keys[:-1]) 
    parent[keys[-1]] = value 

result = {} 
set_target(result, yourlist[:-1], yourlist[-1]) 

Функции get_target() и set_target() повторно использовать на уже построенных вложенных структур, они не ограничены к созданию словаря с нуля. Я адаптировал get_target() от earlier, related post.

Демо:

>>> def get_target(d, keys): 
...  return reduce(lambda d, k: d.setdefault(k, {}), keys, d) 
... 
>>> def set_target(d, keys, value): 
...  parent = get_target(d, keys[:-1]) 
...  parent[keys[-1]] = value 
... 
>>> result = {} 
>>> yourlist = ['item1', 'item2', 'item3', 'item4'] 
>>> set_target(result, yourlist[:-1], yourlist[-1]) 
>>> result 
{'item1': {'item2': {'item3': 'item4'}}} 
+0

Опять же - это решение имеет преимущество сложности - рекурсия O (n!), что один O (n) – volcano