2015-03-24 23 views

Trả lời

17

Without NumPy (ndarray.flatten), bạn có thể sử dụng chain.from_iterable đó là một nhà xây dựng thay thế cho itertools.chain:

>>> list(chain.from_iterable([[1,2,3],[1,2],[1,4,5,6,7]])) 
[1, 2, 3, 1, 2, 1, 4, 5, 6, 7] 

bạn cũng có thể sử dụng reduce trong python 2 và functools.reduce trong 3 đó là hiệu quả hơn cho các danh sách ngắn:

>>> reduce(lambda x,y :x+y ,[[1,2,3],[1,2],[1,4,5,6,7]]) 
[1, 2, 3, 1, 2, 1, 4, 5, 6, 7] 

Hoặc sử dụng một danh sách hiểu:

[j for i in [[1,2,3],[1,2],[1,4,5,6,7]] for j in i] 

benchmark:

:~$ python -m timeit "from itertools import chain;chain.from_iterable([[1,2,3],[1,2],[1,4,5,6,7]])" 
1000000 loops, best of 3: 1.58 usec per loop 
:~$ python -m timeit "reduce(lambda x,y :x+y ,[[1,2,3],[1,2],[1,4,5,6,7]])" 
1000000 loops, best of 3: 0.791 usec per loop 
:~$ python -m timeit "[j for i in [[1,2,3],[1,2],[1,4,5,6,7]] for j in i]" 
1000000 loops, best of 3: 0.784 usec per loop 

Một benchmark trên @ câu trả lời của Will rằng sử dụng sum (nhanh của nó đối với danh sách ngắn nhưng không phải cho danh sách dài):

:~$ python -m timeit "sum([[1,2,3],[4,5,6],[7,8,9]], [])" 
1000000 loops, best of 3: 0.575 usec per loop 
:~$ python -m timeit "sum([range(100),range(100)], [])" 
100000 loops, best of 3: 2.27 usec per loop 
:~$ python -m timeit "reduce(lambda x,y :x+y ,[range(100),range(100)])" 
100000 loops, best of 3: 2.1 usec per loop 
+0

cách tính tổng ([[1,2,3], [4,5,6], [7,8,9]], []) 'so sánh với các giá trị này? – will

+0

@will cho danh sách ngắn nhanh hơn giảm nhưng đối với danh sách dài hơn thì không! – Kasramvd

1

này sẽ làm việc trong trường hợp cụ thể của bạn. Một hàm đệ quy sẽ làm việc tốt nhất nếu bạn có nhiều cấp độ của vòng lặp lồng nhau.

def flatten(input): 
    new_list = [] 
    for i in input: 
     for j in i: 
      new_list.append(j) 
    return new_list 
+0

Đây là giải pháp duy nhất thực sự hoạt động cho các danh sách lồng nhau sâu. – Johan

9

Chỉ với một danh sách như thế này, mẹo nhỏ gọn yêu thích của tôi chỉ sử dụng sum;

sum có một đối số tùy chọn: sum(iterable [, start]), vì vậy bạn có thể làm:

list_of_lists = [[1,2,3], [4,5,6], [7,8,9]] 
print sum(list_of_lists, []) # [1,2,3,4,5,6,7,8,9] 

làm việc này vì các nhà điều hành + sẽ xảy ra là các nhà điều hành nối cho các danh sách, và bạn đã nói với nó rằng giá trị khởi đầu là [] - danh sách trống.

nhưng documentaion cho sum khuyên bạn nên sử dụng itertools.chain thay vào đó, vì nó rõ ràng hơn nhiều.

+0

Dù sao thì đó là một câu trả lời hay! – Kasramvd

+0

làm thế nào để làm cho danh sách các chuỗi? – pyd

+0

@pyd mã ở trên hoạt động đối với mọi loại đối tượng ... tại sao không kiểm tra trước khi yêu cầu? – will

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