2013-10-21 26 views
22

Chỉ cần bắt đầu toying xung quanh với Python vì vậy hãy chịu với tôi :)Python - Trích xuất hầu hết các danh sách nội

Giả danh sách sau đây, trong đó có danh sách lồng nhau:

[[[[[1, 3, 4, 5]], [1, 3, 8]], [[1, 7, 8]]], [[[6, 7, 8]]], [9]] 

Trong một đại diện khác nhau:

[ 
    [ 
     [ 
      [ 
       [1, 3, 4, 5] 
      ], 
      [1, 3, 8] 
     ], 
     [ 
      [1, 7, 8] 
     ] 
    ], 
    [ 
     [ 
      [6, 7, 8] 
     ] 
    ], 
    [9] 
] 

Bạn sẽ giải nén những danh sách bên trong như thế nào để có kết quả với biểu mẫu sau:

[[1, 3, 4, 5], [1, 3, 8], [1, 7, 8], [6, 7, 8], [9]] 

Rất cám ơn!

EDIT (Cảm ơn @falsetru):

rỗng bên trong danh sách hoặc loại hỗn hợp danh sách này sẽ không bao giờ là một phần của đầu vào.

+2

gì nên được trả lại cho '[[[[[1, 3, 4, 5]], [1, 3, 8]] , [[1, 7, 8]]], [[[6, 7, 8]]], [9, [10]]] 'và' [[[[[1, 3, 4, 5]], [1, 3, 8]], [[1, 7, 8]]], [[[6, 7, 8]]], []] '? – falsetru

+0

Cảm ơn câu hỏi làm rõ: Danh sách trống hoặc danh sách có loại mục hỗn hợp sẽ không bao giờ là một phần của đầu vào –

Trả lời

32

Điều này dường như làm việc, giả sử không có danh sách 'trộn' như [1,2,[3]]:

def get_inner(nested): 
    if all(type(x) == list for x in nested): 
     for x in nested: 
      for y in get_inner(x): 
       yield y 
    else: 
     yield nested 

Sản lượng list(get_inner(nested_list)):

[[1, 3, 4, 5], [1, 3, 8], [1, 7, 8], [6, 7, 8], [9]] 

Hoặc thậm chí ngắn hơn, mà không cần máy phát điện, sử dụng sum để kết hợp các danh sách kết quả :

def get_inner(nested): 
    if all(type(x) == list for x in nested): 
     return sum(map(get_inner, nested), []) 
    return [nested] 
+0

Đẹp! Cảm ơn :) –

13

Sử dụng itertools.chain.from_iterable:

from itertools import chain 

def get_inner_lists(xs): 
    if isinstance(xs[0], list): # OR all(isinstance(x, list) for x in xs) 
     return chain.from_iterable(map(get_inner_lists, xs)) 
    return xs, 

sử dụng isinstance(xs[0], list) thay vì all(isinstance(x, list) for x in xs), vì không có danh sách hỗn hợp/danh sách bên trong trống rỗng.


>>> list(get_inner_lists([[[[[1, 3, 4, 5]], [1, 3, 8]], [[1, 7, 8]]], [[[6, 7, 8]]], [9]])) 
[[1, 3, 4, 5], [1, 3, 8], [1, 7, 8], [6, 7, 8], [9]] 
5

More hiệu quả hơn đệ quy:

result = [] 
while lst: 
    l = lst.pop(0) 
    if type(l[0]) == list: 
     lst += [sublst for sublst in l if sublst] # skip empty lists [] 
    else: 
     result.insert(0, l) 
+3

Xóa mục đầu tiên khỏi danh sách, Chèn vào đầu danh sách mất thời gian O (n). Sử dụng ['collections.deque'] (http://docs.python.org/2/library/collections.html#collections.deque) có thể cải thiện tốc độ. Xem http://ideone.com/RFGhnh – falsetru

+1

Nếu bạn cho rằng giải pháp của mình hiệu quả hơn các giải pháp khác, vui lòng đính kèm điểm chuẩn cho đầu vào nhỏ và lớn. Xem nhận xét của falsetru tại sao nó lại chậm. – pts

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