Не думаю, что это возможно. Мне не удалось найти документацию, в которой это явно указано, но я считаю, что go test
всегда использует каталог пакетов (содержащий исходные исходные файлы) в качестве рабочего каталога.
Дан список списков l
,
flat_list = [элемент для подсписка в l для элемента в подсписке]
, что означает:
flat_list = []
for sublist in l:
for item in sublist:
flat_list.append(item)
быстрее чем ярлыки, опубликованные до сих пор. ( l
- список, который необходимо сгладить.)
Вот соответствующая функция:
flatten = lambda l: [item for sublist in l for item in sublist]
В качестве доказательства вы можете использовать модуль timeit
в стандартной библиотеке:
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 1.1 msec per loop
Объяснение: ярлыки, основанные на +
(включая подразумеваемое использование в sum
), по необходимости, являются O (L ** 2)
, когда есть L подсписок - по мере того, как список промежуточных результатов становится длиннее, на каждом шаге выделяется новый объект списка промежуточных результатов, и все элементы в предыдущем промежуточном результате должны быть скопированы (а также несколько новых добавляются в конце). Итак, для простоты и без потери общности, скажем, у вас есть L подсписок по I элементов в каждом: первые I элементов копируются взад и вперед L-1 раз, вторые I-элементы L-2 раза и так далее; общее количество копий в I раз больше суммы x для x от 1 до L исключено, то есть I * (L ** 2) / 2
.
Компонент списка генерирует только один список один раз , и копирует каждый элемент (из исходного места жительства в список результатов) также ровно один раз.
другой интересный способ сделать это:
from functools import reduce
from operator import add
li=[[1,2],[3,4]]
x= reduce(add, li)
>>> from django.contrib.admin.utils import flatten
>>> l = [[1,2,3], [4,5], [6]]
>>> flatten(l)
>>> [1, 2, 3, 4, 5, 6]
... Панды :
>>> from pandas.core.common import flatten
>>> list(flatten(l))
... Itertools:
>>> import itertools
>>> flatten = itertools.chain.from_iterable
>>> list(flatten(l))
... Matplotlib
>>> from matplotlib.cbook import flatten
>>> list(flatten(l))
... Unipath:
>>> from unipath.path import flatten
>>> list(flatten(l))
... Setuptools:
>>> from setuptools.namespaces import flatten
>>> list(flatten(l))
from nltk import flatten
l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flatten(l)
преимущество этого решения по большинству других здесь - это, если у Вас есть список как:
l = [1, [2, 3], [4, 5, 6], [7], [8, 9]]
, в то время как большинство других решений бросает ошибку, это решение обрабатывает их.
Почему вы используете расширение?
reduce(lambda x, y: x+y, l)
Это должно работать нормально.
Примечание автора : Это неэффективно. Но весело, потому что моноиды потрясающие. Это не подходит для производственного кода Python.
>>> sum(l, [])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Это просто суммирует элементы итерации, переданные в первом аргументе, обрабатывая второй аргумент как начальное значение суммы (если не указано, вместо него используется 0
, и в этом случае будет выдана ошибка) .
Поскольку вы суммируете вложенные списки, вы фактически получаете [1,3] + [2,4]
как результат sum ([[1,3], [2, 4]], [])
, что равно [1,3,2,4]
.
Обратите внимание, что работает только со списками списков. Для списков списков списков вам понадобится другое решение.
[]) , что равно [1,3,2,4]
.
Обратите внимание, что работает только со списками списков. Для списков списков списков вам понадобится другое решение.
[]) , что равно [1,3,2,4]
.
Обратите внимание, что работает только со списками списков. Для списков списков списков вам понадобится другое решение.
from functools import reduce #python 3
>>> l = [[1,2,3],[4,5,6], [7], [8,9]]
>>> reduce(lambda x,y: x+y,l)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Метод extend ()
в вашем примере изменяет x
вместо того, чтобы возвращать полезное значение (которое reduce ()
ожидает
Более быстрый способ выполнить версию reduce
- это
>>> import operator
>>> l = [[1,2,3],[4,5,6], [7], [8,9]]
>>> reduce(operator.concat, l)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Причина, по которой ваша функция не работает, заключается в том, что extension расширяет массив в- место и не возвращает.
Беру свое заявление обратно. сумма не является победителем. Хотя быстрее, когда список невелик. Но производительность значительно снижается с большими списками.
>>> timeit.Timer(
'[item for sublist in l for item in sublist]',
'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10000'
).timeit(100)
2.0440959930419922
Суммарная версия все еще работает более минуты и еще не обработана!
Для средних списков:
>>> timeit.Timer(
'[item for sublist in l for item in sublist]',
'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10'
).timeit()
20.126545906066895
>>> timeit.Timer(
'reduce(lambda x,y: x+y,l)',
'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10'
).timeit()
22.242258071899414
>>> timeit.Timer(
'sum(l, [])',
'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10'
).timeit()
16.449732065200806
Использование небольших списков и timeit: number = 1000000
>>> timeit.Timer(
'[item for sublist in l for item in sublist]',
'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]'
).timeit()
2.4598159790039062
>>> timeit.Timer(
'reduce(lambda x,y: x+y,l)',
'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]'
).timeit()
1.5289170742034912
>>> timeit.Timer(
'sum(l, [])',
'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]'
).timeit()
1.0598428249359131
Вы можете использовать itertools.chain ()
:
>>> import itertools
>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain(*list2d))
или, в Python> = 2.6, использовать itertools.chain.from_iterable ()
который не требует распаковки списка:
>>> import itertools
>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain.from_iterable(list2d))
Этот подход, возможно, более читабелен, чем [элемент для подсписка в l для элемента в подсписке]
, и, похоже, тоже быстрее:
[me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;import itertools' 'list(itertools.chain.from_iterable(l))'
10000 loops, best of 3: 24.2 usec per loop
[me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 45.2 usec per loop
[me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 488 usec per loop
[me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 522 usec per loop
[me@home]$ python --version
Python 2.7.3
Вот функция с помощью рекурсии, которая будет работать над любым произвольным вложенным списком.
def flatten(nested_lst):
""" Return a list after transforming the inner lists
so that it's a 1-D list.
>>> flatten([[[],["a"],"a"],[["ab"],[],"abc"]])
['a', 'a', 'ab', 'abc']
"""
if not isinstance(nested_lst, list):
return(nested_lst)
res = []
for l in nested_lst:
if not isinstance(l, list):
res += [l]
else:
res += flatten(l)
return(res)
>>> flatten([[[],["a"],"a"],[["ab"],[],"abc"]])
['a', 'a', 'ab', 'abc']
Одна строка мы используем +
к спискам concat с обработкой None
, 'hello'
import functools
l = [[1, 2, 3], [4, 5, 6], [7], [8, 9],None,'hello']
functools.reduce(lambda acc,x: x + acc if isinstance(x,list) else acc + [x] ,l,[])
Одна возможность состоит в том, чтобы рассматривать массив как строку:
elements = [[180.0, 1, 2, 3], [173.8], [164.2], [156.5], [147.2], [138.2]]
list(map(float, str(elements).replace("[", "").replace("]", "").split(",")))