Вступление
Список - это самая гибкая структура данных в Python. Принимая во
внимание, что 2D-список, который обычно известен как список списков,
представляет собой объект списка, где каждый элемент является самим
списком, например: [[1,2,3], [4,5,6], [7,8,9]]
.
Сглаживание списка списков влечет за собой преобразование двухмерного
списка в одномерный список путем отмены вложенности каждого элемента
списка, хранящегося в списке списков, т. Е. Преобразование
[[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]
относится к list
типов.
Нерегулярный список списков
Каждый элемент этого списка является либо вложенным списком, либо
элементом, не входящим в список (например, целым числом или строкой).
Следовательно, существует нестыковка по типу элемента. Пример:
[[1, 2, 3], [4, 5], 6]
где [1, 2, 3]
и [4, 5]
относятся к типу
list
а 6
- к типу int
.
Свести Список списков для использования вложенного Loops
Это метод грубой силы для получения плоского списка путем выбора каждого элемента из списка списков и помещения его в одномерный список.
Код интуитивно понятен, как показано ниже, и работает как для обычных, так и для нерегулярных списков списков:
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 (уменьшение () и iconcat ())
Функция iconcat()
выполняет основную операцию конкатенации и
применяется совокупно к элементам списка списков слева направо, чтобы
свести его к одному списку:
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 () )
Этот подход идеально подходит для преобразования двумерного списка в единый плоский список, поскольку он обрабатывает последовательные последовательности как единую последовательность путем последовательного повторения итерации, переданной в качестве аргумента.
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
чтобы
получить одномерный итератор по массиву для достижения нашей цели.
Однако этот подход относительно медленный:
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.
Свести список списков с помощью суммы
Еще одно решение - суммирование по внутренним спискам. Функция имеет два
параметра: 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]
Свести список списков с помощью лямбда
Анонимная функция может быть определена с помощью ключевого слова лямбда. Регулярный / нерегулярный список передается в качестве аргумента этой анонимной функции, и выполняется оценка выражения для получения плоского одномерного списка:
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.