Почему у Python нет функции «сглаживания» для списков?

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, который поставляется с сотней тысяч различных включенных батарей, не обеспечивает простой метод сглаживания массивов? Идея включения такой функции в какой-то момент обсуждалась и отклонялась?

31 голос | спросил Hubro 24 AM00000090000003031 2014, 09:20:30

3 ответа


32

Предложения по функции flatten, добавляемой в стандартную библиотеку, время от времени появляются на python-dev и python- идей . Разработчики Python обычно отвечают следующими моментами:

  1. Одноуровневая сглаженная (превращая итерабельность итераций в один итерабельный) является тривиальным однострочным выражением (x for y in z for x in y) и в любом случае уже находится в стандартной библиотеке под именем itertools.chain.from_iterable

  2. Каковы варианты использования универсального многоуровневого сглаживания? Являются ли они достаточно привлекательными для добавления функции в стандартную библиотеку?

  3. Как будет использоваться многоуровневая плоскость общего назначения, когда нужно сгладить и когда оставить ее в покое? Вы можете подумать, что правило, подобное «сглаживать что-либо, поддерживающее итерируемый интерфейс», будет работать, но это приведет к бесконечному циклу для flatten('a') .

См. например Раймонд Хеттингер :

  

Обсуждалось ad nauseam на comp.lang.python. Люди, похоже,   наслаждайтесь написанием своих версий сглаживания больше, чем поиск законных   которые еще не имеют тривиальных решений.

     

Флатендер общего назначения нуждается в некотором роде, чтобы рассказать, что такое атомное и   что можно далее подразделить. Кроме того, неясно, как алгоритм   следует расширить, чтобы охватить входы с древовидными структурами данных с   данные на узлах, а также листья (предварительный заказ, постобработка, порядок   обход и т. д.)

ответил Gareth Rees 28 PM00000040000004431 2014, 16:40:44
8

Он приходит с таким методом, но он не вызывает его сглаживания. Он называется « цепочка ». Он возвращает итератор, который вам понадобится для использования функции list (), чтобы включить его в список. Если вы не хотите использовать *, вы можете использовать вторую версию «from_iterator». Он работает тот же в Python 3. Он не сработает, если вход списка не является списком списков.

[[1], [2, 3], [3, 4, 5]] #yes
[1, 2, [5, 6]] #no

В свое время был сгладить метод модуль compiler.ast, но это было устарело в 2.6, а затем удалено в 3.0. Регрессия произвольной глубины, необходимая для произвольно вложенных списков, плохо работает с минимальной глубиной рекурсии Python. Основания для удаления компилятора были в основном из-за того, что он был mess . Компилятор был преобразован в ast , но сглаживание оставалось.

Произвольная глубина может быть достигнута с помощью массивов numpy и сглаживания библиотеки.

ответил World Engineer 24 AM00000090000002231 2014, 09:38:22
-2

... может быть, потому что это не так сложно написать сами.

def flatten(l): return flatten(l[0]) + (flatten(l[1:]) if len(l) > 1 else []) if type(l) is list else [l]

... и затем сгладить все, что вы хотите:)

>>> flatten([1,[2,3],4])
[1, 2, 3, 4]
>>> flatten([1, [2, 3], 4, [5, [6, {'name': 'some_name', 'age':30}, 7]], [8, 9, [10, [11, [12, [13, {'some', 'set'}, 14, [15, 'some_string'], 16], 17, 18], 19], 20], 21, 22, [23, 24], 25], 26, 27, 28, 29, 30])
[1, 2, 3, 4, 5, 6, {'age': 30, 'name': 'some_name'}, 7, 8, 9, 10, 11, 12, 13, set(['set', 'some']), 14, 15, 'some_string', 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
>>> 
ответил Shreyas 8 PMpFri, 08 Apr 2016 16:16:46 +030016Friday 2016, 16:16:46

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132