Автор оригинала: Raksha Shenoy.
Питон: Как сгладить список списков
Вступление
Список – это самая гибкая структура данных в Python. В то время как 2D – список, который обычно известен как список списков, является объектом списка, где каждый элемент является самим списком- например: [[1,2,3], [4,5,6], [7,8,9]]
.
Выравнивание списка списков влечет за собой преобразование 2D-списка в 1D – список путем удаления вложенности каждого элемента списка, хранящегося в списке списков, т. е. [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
в [1, 2, 3, 4, 5, 6, 7, 8, 9]
.
Процесс выравнивания может быть выполнен с помощью вложенных циклов for, понимания списков, рекурсии, встроенных функций или путем импорта библиотек в Python в зависимости от регулярности и глубины вложенных списков.
Типы вложенных списков
Поскольку Python слабо типизирован, вы можете столкнуться с регулярными и нерегулярными списками списков.
Обычный список списков
Каждый элемент этого списка является подсписком, тем самым соблюдая единообразие типа элемента. Пример: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
представляет собой обычный список списков в виде [1, 2, 3], [4, 5, 6], [7, 8, 9]
имеет тип список
.
Нерегулярный список списков
Каждый элемент этого списка является либо подсписком, либо элементом, не входящим в список (например, целым числом или строкой). Следовательно, существует неравномерность с точки зрения типа элемента. Пример: [[1, 2, 3], [4, 5], 6]
где [1, 2, 3]
и [4, 5]
имеют тип список
и 6
имеет тип int
.
Сглаживание списка списков с помощью вложенных циклов for
Это грубый подход к получению плоского списка путем выбора каждого элемента из списка списков и помещения его в 1D-список.
Код интуитивно понятен, как показано ниже, и работает как для регулярных, так и для нерегулярных списков списков:
def flatten_list(_2d_list): flat_list = [] # Iterate through the outer list for element in _2d_list: if type(element) is list: # If the element is of type list, iterate through the sublist for item in element: flat_list.append(item) else: flat_list.append(element) return flat_list nested_list = [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] print('Original List', nested_list) print('Transformed Flat List', flatten_list(nested_list))
Это приводит к:
Original List [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] Transformed Flat List [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Сглаживание списка списков С помощью понимания списка
Этот подход обеспечивает элегантное, но менее интуитивное решение для создания плоского списка на основе существующего 2D-списка:
regular_list = [[1, 2, 3, 4], [5, 6, 7], [8, 9]] flat_list = [item for sublist in regular_list for item in sublist] print('Original list', regular_list) print('Transformed list', flat_list)
Что привело бы к следующему результату:
Original list [[1, 2, 3, 4], [5, 6, 7], [8, 9]] Transformed list [1, 2, 3, 4, 5, 6, 7, 8, 9]
Сглаживание списка списков рекурсивно
2D-список также может быть расплющен рекурсивно. Приведенная ниже реализация работает как для регулярного, так и для нерегулярного списка списков:
def flatten(list_of_lists): if len(list_of_lists) == 0: return list_of_lists if isinstance(list_of_lists[0], list): return flatten(list_of_lists[0]) + flatten(list_of_lists[1:]) return list_of_lists[:1] + flatten(list_of_lists[1:]) print(flatten([[1, 2, 3, 4], [5, 6, 7], [8, 9], 10]))
Что дало бы нам:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Использование библиотек
Вы также можете положиться на помощь библиотек Pyhon для этой задачи.
Сгладить список списков с помощью functools (reduce() и i concat())
Функция concat()
выполняет основную операцию конкатенации и применяется кумулятивно к элементам списка списков слева направо, чтобы свести его к одному списку:
import functools import operator regular_list = [] # Transform irregular 2D list into a regular one. def transform(nested_list): for ele in nested_list: if type(ele) is list: regular_list.append(ele) else: regular_list.append([ele]) return regular_list irregular_list = [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10], 11] regular_2D_list = transform(irregular_list) print('Original list', irregular_list) print('Transformed list', functools.reduce(operator.iconcat, regular_2D_list, []))
Что дало бы нам желаемый результат:
Original list [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10], 11] Transformed list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Сгладить список списков с помощью itertools (chain())
Этот подход идеально подходит для преобразования 2-D списка в единый плоский список, поскольку он рассматривает последовательные последовательности как единую последовательность, последовательно повторяя итерацию, передаваемую в качестве аргумента.
import itertools regular_list = [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] flat_list = list(itertools.chain(*regular_list)) print('Original list', regular_list) print('Transformed list', flat_list)
Опять же, это дало бы нам сплющенный список в качестве вывода:
Original list [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] Transformed list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Сгладить список списков с помощью numpy (concatenate() и flat())
Numpy предлагает общие операции, которые включают конкатенацию регулярных 2D-массивов по строкам или столбцам. Мы также используем атрибут flat
для получения 1D-итератора над массивом для достижения нашей цели. Однако этот подход является относительно медленным:
import numpy regular_list = [[1, 2, 3, 4], [5, 6, 7], [8, 9]] flat_list = list(numpy.concatenate(regular_list).flat) print('Original list', regular_list) print('Transformed list', flat_list)
Что дает нам желаемый результат:
Original list [[1, 2, 3, 4], [5, 6, 7], [8, 9]] Transformed list [1, 2, 3, 4, 5, 6, 7, 8, 9]
Использование Встроенных Функций
Задача выравнивания также может быть выполнена с помощью встроенных функций, которые предлагает Python.
Сгладить список списков с помощью sum
Суммирование по внутренним спискам-это еще одно решение. Функция имеет два параметра: iterable
, который является списком списков, и start
, который является пустым списком в нашем случае, который служит исходным плоским списком, к которому добавляются элементы внутренних подсписков.
Этот подход удобен тем, что вам не нужно ничего импортировать, но он медленнее, чем функции itertools()
и chain()
при большом количестве подсписков:
regular_list = [[1, 2, 3, 4], [5, 6, 7], [8, 9]] flat_list = sum(regular_list, []) print('Original list', regular_list) print('Transformed list', flat_list)
С выходом:
Original list [[1, 2, 3, 4], [5, 6, 7], [8, 9]] Transformed list [1, 2, 3, 4, 5, 6, 7, 8, 9]
Сглаживание списка списков с помощью Лямбды
Анонимная функция может быть определена с помощью ключевого слова lambda. Регулярный/нерегулярный список передается в качестве аргумента этой анонимной функции, и вычисление выражения выполняется для получения плоского 1D-списка:
irregular_list = [[1, 2, 3], [3, 6, 7], [7, 5, 4],7] # Using lambda arguments: expression flatten_list = lambda irregular_list:[element for item in irregular_list for element in flatten_list(item)] if type(irregular_list) is list else [irregular_list] print("Original list ", irregular_list) print("Transformed List ", flatten_list(irregular_list))
Мы бы снова получили желаемый результат:
Original list [[1, 2, 3], [3, 6, 7], [7, 5, 4], 7] Transformed List [1, 2, 3, 3, 6, 7, 7, 5, 4, 7]
Вывод
В этой статье мы представили обширный список способов, которыми мы можем выполнить задачу выравнивания списка списков в Python.