2011-07-27 44 views
7

Tôi đang mắc kẹt trên một vấn đề nhỏ nhưng phức tạp kể từ hôm qua.Python - Lặp lại trên danh sách lồng nhau

gì tôi có là một (có thể là vô hạn) lồng danh sách như thế này:

[1,[2,[3,4]]] 
or [[1,2],[3,4]] and so on. 

Trên mỗi mức độ danh sách bao gồm hai danh sách phụ, (tôi không sử dụng các bộ vì danh sách có thể sẽ có được chiều dài tùy ý trong bước tiếp theo) Bây giờ tôi muốn chèn phần tử vào mọi vị trí có thể có trong danh sách này và trả về danh sách liệt kê tất cả các vị trí chèn có thể có. Vì vậy, nếu tôi chèn 5, sản lượng của tôi sẽ giống như thế:

[ [5,[1,[2,[3,4]]]], 
[1,[5,[2,[3,4]]]], 
[1,[2,[5,[3,4]]]], 
[1,[2,[[3,5],4]]], 
[1,[2,[3,[4,5]]]] ] 

Nền: Tôi đang cố gắng để xây dựng một cây phả hệ bằng cách thêm một đơn vị phân loại tại một thời điểm. Mỗi taxon phải được chèn vào vị trí phù hợp nhất.

Những gì tôi có bây giờ là:

def get_trees(nwklist,newid): 
    if not isinstance(nwklist,list): 
     return [newid,nwklist] 
    else: 
     return [newid,nwklist],[get_trees(nwklist[0],newid),nwklist[1]],[nwklist[0],get_trees(nwklist[1],newid)] 

mà không sản xuất đầu ra tôi muốn, nhưng đi kèm hơi gần.

([5, [1, [2, [3, 4]]]], 
[[5, 1], [2, [3, 4]]], 
[1, ([5, [2, [3, 4]]], [[5, 2], [3, 4]], [2, ([5, [3, 4]], [[5, 3], 4], [3, [5, 4]])])]) 

Có một giải pháp dễ dàng, có thể liên quan đến các hàm lambda, nhưng tôi không thấy nó.

Christoph

+6

Bạn gần như chắc chắn đang phát minh lại bánh xe. Có các gói để xử lý cây phát sinh loài trong Python, giống như Phylo của Biopython (http://www.biopython.org/wiki/Phylo) hoặc dendropy (http://pypi.python.org/pypi/DendroPy) –

+0

Chỉ cần nitpicking: danh sách có thể có * độ sâu tùy ý *, nhưng không phải * chiều sâu * vô hạn. Ít nhất, tôi không biết làm thế nào nó có thể. –

+0

"Mỗi taxon phải được chèn vào vị trí phù hợp nhất." Điều này nghe như cố gắng xây dựng một cây hàng xóm tham gia, đó là một kế hoạch xấu. Tra cứu thêm một số tài liệu về cách tốt nhất để cấu thành cây phylogentic và tại sao cách dễ nhất cũng là điều tồi tệ nhất. – pyvi

Trả lời

2

Tôi muốn sử dụng một máy phát điện:

def gen_trees(nwklist, newid): 
    yield [newid] + [nwklist] 
    if isinstance(nwklist, list): 
    for i in xrange(len(nwklist)): 
     for l in gen_trees(nwklist[i], newid): 
     yield nwklist[:i] + [l] + nwklist[i+1:] 
    yield [nwklist] + [newid] 

for l in gen_trees([1,[2,[3,4]]] , 5): 
    print l 

Xin lưu ý rằng đây trả về nhiều cây hơn được liệt kê trong ví dụ của bạn:

[5, [1, [2, [3, 4]]]] 
[[5, 1], [2, [3, 4]]] 
[[1, 5], [2, [3, 4]]] 
[1, [5, [2, [3, 4]]]] 
[1, [[5, 2], [3, 4]]] 
[1, [[2, 5], [3, 4]]] 
[1, [2, [5, [3, 4]]]] 
[1, [2, [[5, 3], 4]]] 
[1, [2, [[3, 5], 4]]] 
[1, [2, [3, [5, 4]]]] 
[1, [2, [3, [4, 5]]]] 
[1, [2, [[3, 4], 5]]] 
[1, [[2, [3, 4]], 5]] 
[[1, [2, [3, 4]]], 5] 

Theo như tôi thấy, này ahderes để các yêu cầu đã nêu. Nếu có một số yêu cầu không được nêu ra mà tôi đã không nhận được (ví dụ: nếu phần tử đầu tiên của mỗi danh sách phụ phải là vô hướng), vui lòng làm rõ và tôi sẽ cập nhật giải pháp.

+0

Cảm ơn! Điều đó có vẻ rất tốt. Đó là sau đó tôi liệt kê, tôi quên đề cập đến thứ tự là không quan trọng, vì vậy [1, [[5, 2], [3, 4]]] [1, [[2, 5], [3 , 4]]] về cơ bản là cùng một cây. – Christoph

+0

Và nếu tôi loại bỏ dòng sản phẩm thứ hai [nwklist] + [newid], tôi nhận được chính xác những gì tôi muốn. Cảm ơn rất nhiều! – Christoph

Các vấn đề liên quan