2012-11-05 24 views
7

Giả sử tôi đã có một danh sách như sau:Có thể biến danh sách thành một dict lồng nhau của các phím * mà không cần * đệ quy không?

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

Có thể tạo, khỏi danh sách này, dict sau mà không sử dụng đệ quy/một hàm đệ quy?

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

Vâng, đệ quy === lặp, do đó, có. Bạn có bất kỳ mã nào để hiển thị những gì bạn đã thử không? Có lẽ một câu trả lời có thể xây dựng từ đó. – Makoto

+0

bạn có thể sử dụng đơn giản 'map',' reduce' –

+0

@Makoto không có trường hợp sử dụng cụ thể nào mà tôi có. Tôi chỉ đơn giản là xem xét một số dự án FOSS và nhận thấy rằng hầu hết, nếu không phải tất cả, sử dụng đệ quy (không chính xác). Nó chỉ khiến tôi suy nghĩ xem liệu có một sự thay thế cho đệ quy hay không. Câu trả lời của Óscar López khá sâu sắc (đặc biệt là liên kết). –

Trả lời

3

Đối với trường hợp đơn giản này ít nhất, vâng:

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

Đối với trường hợp đơn giản, bạn chỉ cần lặp và xây dựng, hoặc là từ cuối cùng hoặc khi bắt đầu:

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

hoặc

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

Các giải pháp đầu tiên cũng có thể được diễn tả như một lớp lót bằng reduce():

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

Bí quyết tốt đẹp trên đảo ngược. – kindall

+0

Vâng, điều này vượt trội hơn câu trả lời của tôi. –

1

Đó là đáng nói đến là every recursion can be converted into iteration, mặc dù đôi khi có thể không dễ dàng như vậy. Đối với ví dụ cụ thể trong câu hỏi, nó đủ đơn giản, nó chỉ là vấn đề tích lũy kết quả mong đợi trong một biến và duyệt qua danh sách đầu vào theo thứ tự thích hợp. Đây là những gì tôi muốn nói:

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

Hoặc thậm chí ngắn hơn, thuật toán trên có thể được thể hiện dưới dạng một lớp lót (giả sử Python 2.x, bằng Python 3.x reduce đã được chuyển đến các mô-đun functools). Chú ý tên biến trong dung dịch trước đó tương ứng với các thông số của lambda, và làm thế nào trong cả hai trường hợp, các giá trị ban đầu của ắc là {}:

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

Dù bằng cách nào, chức năng convert tác phẩm như mong đợi:

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

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

Cảm ơn bạn đã liên kết - rất sâu sắc! –

3

Hoặc cho fancyness và giảm khả năng đọc:

dict = reduce(lambda x, y: {y: x}, reversed(myList), {}) 
Các vấn đề liên quan