2012-11-05 9 views
7

Przypuśćmy miałem listę następująco:Czy można zmienić listę w zagnieżdżony dyktat kluczy * bez * rekursji?

mylist = ['a','b','c','d'] 

Czy to możliwe, aby tworzyć, z tej listy, co następuje DICT bez użyciem rekurencji/rekurencyjną funkcję?

{ 
    'a': { 
    'b': { 
     'c': { 
     'd': { } 
     } 
    } 
    } 
} 
+0

Cóż, rekurencja === iteracja, więc tak. Czy masz jakiś kod, aby pokazać, co próbujesz? Być może odpowiedź może z tego wyjść. – Makoto

+0

można użyć po prostu 'map',' zmniejszyć' –

+0

@Makoto nie ma konkretnego przypadku użycia, które mam na myśli. Po prostu przeglądałem kilka projektów FOSS i zauważyłem, że większość, jeśli nie wszystkie, używa rekurencji (nie jest niepoprawna). Po prostu zastanawiałem się, czy istnieje alternatywa dla rekurencji. Odpowiedź Óscar López jest dość wnikliwa (zwłaszcza link). –

Odpowiedz

3

W tym prostym przypadku przynajmniej tak:

my_list = ['a', 'b', 'c', 'd'] 
cursor = built_dict = {} 
for value in my_list: 
    cursor[value] = {} 
    cursor = cursor[value] 
0
mydict = dict() 
currentDict = mydict 
for el in mylist: 
    currentDict[el] = dict() 
    currentDict = currentDict[el] 
11

Dla prostego przypadku, po prostu iteracyjne i budować, albo z końcem lub początkiem:

result = {} 
for name in reversed(mylist): 
    result = {name: result} 

lub

result = current = {} 
for name in mylist: 
    current[name] = {} 
    current = current[name] 

Pierwszym rozwiązaniem może być również wyrażony jako jedną wkładką wykorzystaniem reduce():

reduce(lambda res, name: {name: res}, reversed(mylist), {}) 
+1

Dobra sztuczka na odwróconej. – kindall

+0

Tak, to jest lepsze od mojej odpowiedzi. –

1

Warto wspomnieć, że every recursion can be converted into iteration, chociaż czasami, że może nie być tak łatwo. Dla szczególnego przykładu w tym pytaniu, jest to prosta sprawa, to tylko kwestia zebrania oczekiwanego wyniku w zmiennej i przejścia przez listę wejściową w odpowiedniej kolejności. To, co mam na myśli:

def convert(lst): 
    acc = {} 
    for e in reversed(lst): 
     acc = {e: acc} 
    return acc 

Albo jeszcze krócej, powyższy algorytm może być wyrażona jako jedno-liner (zakładając Pythona 2.x, w Pythonie 3.x reduce został przeniesiony do modułu functools). Zauważ, że nazwy zmiennych w poprzednim rozwiązaniu odpowiadają parametrami lambda, a jak w obu przypadkach wartość początkowa akumulatora jest {}:

def convert(lst): 
    return reduce(lambda acc, e: {e: acc}, reversed(lst), {}) 

Tak czy inaczej, funkcja convert działa zgodnie z oczekiwaniami:

mylist = ['a','b','c','d'] 
convert(mylist) 

=> {'a': {'b': {'c': {'d': {}}}}} 
+1

Dzięki za link - bardzo wnikliwe! –

3

Lub fancyness i zmniejszenie czytelności:

dict = reduce(lambda x, y: {y: x}, reversed(myList), {})