Преобразование многомерного списка в 1D-список в Python

Многомерный список, такой как l=[[1,2],[3,4]] можно преобразовать в 1D, выполнив sum(l,[]) . Может ли кто-нибудь объяснить, как это происходит?

Ответчик сказал, что этот метод можно использовать только для «сглаживания» 2D-списка – что он не будет работать для более высоких многомерных списков. Но это происходит, если повторять. Например, если A является 3D-списком, тогда сумма (сумма (A), []), []) сгладит A до 1D-списка.

sum добавляет последовательность вместе с помощью оператора + . например, sum([1,2,3]) == 6 . Второй параметр является необязательным стартовым значением, которое по умолчанию равно 0. Например, sum([1,2,3], 10) == 16 .

В вашем примере это [] + [1,2] + [3,4] где + в 2 списках объединяет их вместе. Поэтому результат [1,2,3,4]

Пустой список требуется в качестве второго параметра для sum потому что, как упоминалось выше, значение по умолчанию равно sum чтобы добавить к 0 (то есть 0 + [1,2] + [3,4] ), что приведет к неподдерживаемому типу операнда ( s) для +: 'int' и 'list'

Это соответствующий раздел справки для sum :

sum (sequence [, start]) -> value

Возвращает сумму последовательности чисел (NOT string) плюс значение параметра «start» (по умолчанию 0).

Заметка

Как wallacoloo comented это не общее решение для сглаживания любого многомерного списка. Он просто работает для списка 1D-списков из-за поведения, описанного выше.

Обновить

Для способа сгладить 1 уровень вложенности см. Этот рецепт на странице itertools :

 def flatten(listOfLists): "Flatten one level of nesting" return chain.from_iterable(listOfLists) 

Чтобы сгладить более глубоко вложенные списки (включая нерегулярно вложенные списки), см. Принятый ответ на этот вопрос (есть и другие вопросы, связанные с этим вопросом).

Обратите внимание, что рецепт возвращает объект itertools.chain (который итерируется), а ответ другого вопроса возвращает объект- generator поэтому вам нужно обернуть любой из них в list вызовов, если вы хотите полный список, а не итерацию по нему. например list(flatten(my_list_of_lists)) .

Если ваш список nested , как вы говорите, «2D» (это означает, что вы хотите только идти на один уровень вниз, а все 1-уровневые элементы nested списков), простое понимание списка:

 flat = [x for sublist in nested for x in sublist] 

это подход, который я бы рекомендовал – гораздо эффективнее, чем sum ming ( sum предназначена для чисел – это было просто слишком беспокоиться, чтобы каким-то образом блокировать все попытки «суммировать» не номера … Я был оригинальным разработчиком и первым исполнителем sum в стандартной библиотеке Python, поэтому, я думаю, я должен знать ;-).

Если вы хотите спуститься «как можно глубже» (для глубоко вложенных списков), рекурсия – самый простой способ, хотя, устраняя рекурсию, вы можете получить более высокую производительность (по цене более высокой сложности).

Этот рецепт предлагает рекурсивное решение, устранение рекурсии и другие подходы (все поучительные, хотя и не такие простые, как однострочный, который я предложил ранее в этом ответе).

Это похоже на то, что вы ищете окончательный ответ:

 [3, 7] 

Для этого вам лучше всего составить список

 >>> l=[[1,2],[3,4]] >>> [x+y for x,y in l] [3, 7] 

Для любого типа многодиапазонного массива этот код будет сглаживаться в одном измерении:

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

Я написал программу для многомерного сглаживания с использованием рекурсии. Если у кого-то есть комментарии по улучшению программы, вы всегда можете видеть меня улыбающимся:

 def flatten(l): lf=[] li=[] ll=[] p=0 for i in l: if type(i).__name__=='list': li.append(i) else: lf.append(i) ll=[x for i in li for x in i] lf.extend(ll) for i in lf: if type(i).__name__ =='list': #not completely flattened flatten(lf) else: p=p+1 continue if p==len(lf): print(lf) 

Оператор + конкатенирует списки, а начальное значение – [] – пустой список.