2015-03-24 7 views

ответ

17

Без Numpy (ndarray.flatten), вы можете использовать chain.from_iterable, который является альтернативным конструктор 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] 

также вы можете использовать reduce в Python 2 и functools.reduce в 3, что является более эффективным для коротких списков:

>>> 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] 

Или использовать список понимание:

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

тест:

:~$ 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 

Ориентиром на @ ответ Уилла, который использовал sum (его быстро на короткий список, но не для длинного списка):

:~$ 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

как 'sum ([[1,2,3], [4,5,6], [7,8,9]], [])' сравнивают с этими? – will

+0

@will для коротких списков его быстрее, чем сокращение, но для более длинных списков его нет! – Kasramvd

1

Это будет работать в вашем конкретном случае. Рекурсивная функция будет работать лучше всего, если у вас есть несколько уровней вложенных итераций.

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

Это единственное решение, которое действительно работает для глубоко вложенных списков. – Johan

9

Для всего списка, как это, мой любимый аккуратный маленький трюк просто использовать sum;

sum имеет дополнительный аргумент: sum(iterable [, start]), так что вы можете сделать:

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] 

это работает, потому что оператор + случается оператор конкатенации списков, и вы сказали, что это начальное значение является [] - пустой список.

, но документ для sum рекомендует вместо этого использовать itertools.chain, так как он намного яснее.

+0

В любом случае, это хороший ответ! – Kasramvd

+0

как сделать для списка строк? – pyd

+0

@pyd код выше работает для любого типа объекта ... почему бы не проверить перед запросом? – will

Смежные вопросы