2012-11-05 2 views
7

Gesetzt ich eine Liste hatte, wie folgt:Ist es möglich, eine Liste in ein verschachteltes Diktat von Schlüsseln umzuwandeln * ohne * Rekursion?

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

Ist es möglich, aus dieser Liste zu erstellen, die folgende dict ohne mit Rekursion/eine rekursive Funktion?

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

Nun, Rekursion === Iteration, also ja. Hast du einen Code, um zu zeigen, was du probiert hast? Vielleicht kann eine Antwort darauf aufbauen. – Makoto

+0

können Sie einfach 'map' verwenden,' reduce' –

+0

@Makoto gibt es keinen bestimmten Anwendungsfall, den ich mir vorstelle. Ich habe einfach eine Reihe von FOSS-Projekten überprüft und festgestellt, dass die meisten, wenn nicht alle, Rekursionen verwendeten (nicht falsch). Es hat mich nur darüber nachdenken lassen, ob es eine Alternative zur Rekursion gibt. Die Antwort von Óscar López ist eher aufschlussreich (speziell der Link). –

Antwort

3

Für diesen einfachen Fall zumindest, ja:

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

Für den einfachen Fall, einfach durchlaufen und bauen, entweder vom Ende oder der Anfang:

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

oder

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

Die erste Lösung kann auch als Einzeiler ausgedrückt werden reduce() mit:

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

Netter Trick auf dem umgekehrten. – kindall

+0

Ja, das ist meiner Antwort überlegen. –

1

Es ist erwähnenswert, dass every recursion can be converted into iteration, wenn auch manchmal, dass nicht so einfach sein könnte. Für das spezielle Beispiel in der Frage ist es ist einfach genug, es ist nur eine Frage der Anhäufung des erwarteten Ergebnisses in einer Variablen und durchläuft die Eingabeliste in der richtigen Reihenfolge. Das ist, was ich meine:

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

Oder noch kürzer, kann der obige Algorithmus als Einzeiler ausgedrückt werden (vorausgesetzt, Python 2.x, in Python 3.x reduce zum functools Modul bewegt wurde). Beachten Sie, wie die Variablennamen in der vorherigen Lösung der Lambda-Parameter entsprechen, und wie in den beiden Fällen ist der Anfangswert des Akkumulators {}:

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

So oder so, die Funktion convert Arbeiten wie erwartet:

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

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

Danke für den Link - sehr aufschlussreich! –

3

Oder fancyness und reduzierte Lesbarkeit:

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