Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

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

sum (sequence [, start]) → значение

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

Примечание

Как wallacoloo, это означает не общее решение для выравнивания любого многомерного списка. Он просто работает для списка 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)).

Ответ 2

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

[3, 7]

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

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

Ответ 5

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

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)

Ответ 6

Я написал эту функцию:

def make_array_single_dimension(l):
    l2 = []

    for x in l:
        if type(x).__name__ == "list":
            l2 += make_array_single_dimension(x)
        else:
            l2.append(x)

    return l2

Это работает также!

Ответ 7

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