Erlang и Ruby имеют функции для выравнивания массивов. Похоже, такой простой и полезный инструмент для добавления в язык. Можно сделать это:
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> mess.flatten()
[1, 2, 3, 4, 5, 6]
Или даже:
>>> import itertools
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> list(itertools.flatten(mess))
[1, 2, 3, 4, 5, 6]
Вместо этого в Python приходится сталкиваться с проблемой написания функции для выравнивания массивов с нуля. Это кажется мне глупым, сглаживание массивов - это обычное дело. Это как написать пользовательскую функцию для объединения двух массивов.
Я прогуглил это бесполезно, поэтому я спрашиваю здесь; Есть ли конкретная причина, почему зрелый язык, такой как Python 3, который поставляется с сотнями тысяч различных батарей, не обеспечивает простой метод выравнивания массивов? Была ли идея включения такой функции обсуждена и отвергнута в какой-то момент?
python
python-3.x
Hubro
источник
источник
extend
но сплющить было бы намного элегантнее. Тем не менее, я думаю, что этот шаблон достаточно распространен, чтобы оправдать сглаживание в стандартной библиотеке.Ответы:
Предложения по добавлению
flatten
функции в стандартную библиотеку время от времени появляются в списках рассылки python-dev и python-ideas . Разработчики Python обычно отвечают следующими моментами:Одноуровневое выравнивание (превращение итерируемой итерации в одну итерацию) - это тривиальное однострочное выражение, которое
(x for y in z for x in y)
в любом случае уже находится в стандартной библиотеке под именемitertools.chain.from_iterable
.Каковы варианты использования универсального многоуровневого выравнивания? Действительно ли они достаточно убедительны для добавления функции в стандартную библиотеку?
Как бы универсальное многоуровневое выравнивание решало, когда выравнивать, а когда оставить в покое? Вы можете подумать, что будет работать правило типа «сплющить все, что поддерживает итеративный интерфейс», но это приведет к бесконечному циклу for
flatten('a')
.Смотрите, например, Раймонд Хеттингер :
источник
flatten
функция может быть определена какlambda z: [x for y in z for x in y]
.flatten
метод. Реализация этого метода должна рекурсивно вызыватьflatten
его подкомпонент, если объект является составным. К сожалению, AFAIK не каждое значение является объектом в Python. В Ruby это должно работать, хотя.Он поставляется с таким методом, но не вызывает его сглаживания. Это называется " цепь ". Он возвращает итератор, который вам затем потребуется использовать функцию list (), чтобы превратить его в список. Если вы не хотите использовать *, вы можете использовать вторую версию from_iterator. Он работает так же в Python 3. Он потерпит неудачу, если входной список не является списком списков.
Был одно время Flatten метода в модуле compiler.ast , но это было устаревшим в 2.6 , а затем удален в 3.0. Произвольная рекурсия глубины, необходимая для произвольно вложенных списков, плохо работает с консервативной максимальной глубиной рекурсии Python. Причины для удаления компилятора были в значительной степени из-за того, что это беспорядок . Компилятор превратился в ast, но flatten остался позади.
Произвольная глубина может быть достигнута с помощью массивов numpy и выравнивания этой библиотеки.
источник
chain.from_iterator
вы сказали, функция может использоваться только для выравнивания двумерных списков. Actualy расплющить функция, которая принимает любые суммы вложенных списков и возвращает одномерный списка, все равно будет массово полезно во многих случаях ( по крайней мере , на мой взгляд)... может быть, потому что это не так сложно написать самостоятельно
... а потом расплющить сколько хочешь :)
источник