Перейти к содержимому

Как из списка делать вложенные списки python

  • автор:

Преобразование списка списков в плоский список в Python

Часто при работе с данными в Python возникает необходимость преобразования списка списков в плоский список. Например, имеется следующий список списков:

Алексей Кодов
Автор статьи
7 июля 2023 в 17:21

Часто при работе с данными в Python возникает необходимость преобразования списка списков в плоский список. Например, имеется следующий список списков:

list_of_lists = [ [1, 2, 3], [4, 5, 6], [7], [8, 9] ]

Цель состоит в том, чтобы получить плоский список, то есть одномерный список, который будет выглядеть так:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

Эта задача может быть решена несколькими способами в Python.

Использование вложенного цикла for

Первый и самый простой способ — это использование вложенного цикла for. Внешний цикл проходит через каждый список в списке списков, а внутренний цикл проходит через каждый элемент этих списков.

flat_list = [] for sublist in list_of_lists: for item in sublist: flat_list.append(item)

Использование функции sum

Функция sum в Python может использоваться для конкатенации списков. Второй аргумент функции sum является начальным значением. Если начальное значение — пустой список, то функция sum объединит все списки в один.

flat_list = sum(list_of_lists, [])

Использование генератора списков

Генераторы списков — это эффективный инструмент Python для создания списков. Они могут быть использованы для создания плоского списка из списка списков.

flat_list = [item for sublist in list_of_lists for item in sublist]

Использование функции chain из модуля itertools

Модуль itertools в Python содержит функцию chain, которая может быть использована для создания плоского списка из списка списков.

from itertools import chain flat_list = list(chain(*list_of_lists))

Таким образом, в Python есть несколько способов преобразования списка списков в плоский список. Выбор конкретного метода зависит от конкретной задачи и предпочтений разработчика.

Списки в Python

В Python есть множество комплексных типов данных, называемых последовательностями. Список — один из часто используемых и универсальных типов данных. Это аналог массивов в других языках программирования.

Как создать список

Список можно создать, записав его будущие элементы в квадратные скобки [] через запятую.

В списке допускается любое количество элементов разных типов (целые числа, числа с плавающей точкой, строки и т. д.).

# пустой список my_list = [] # список целых чисел my_list = [1, 2, 3] # список с элементами разных типов my_list = [1, "Привет", 3.4]

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

# внутри основного списка — вложенный список my_list = ["мышь", [8, 4, 6], ['a']]

Как получить доступ к элементам списка

1. По индексу

Чтобы получить доступ к элементу списка, можно воспользоваться оператором индекса [] .

Примечание. Обратите внимание, что индексирование кортежа начинается с 0. Поэтому у списка из 5 элементов будут индексы с 0 по 4.

Попытка взять элемент по индексу, не входящему в диапазон, приведет к IndexError. Индекс — обязательно целое число. Нельзя использовать числа с плавающей точкой и другие типы, это приведет к TypeError.

Вложенные списки можно получить с помощью вложенной индексации.

# Индексация списков my_list = ['п', 'р', 'о', 'б', 'а'] # Вывод: п print(my_list[0]) # Вывод: о print(my_list[2]) # Вывод: а print(my_list[4]) # Вложенный список — [2, 0, 1, 5] n_list = ["Счастье", [2, 0, 1, 5]] # Вложенная индексация print(n_list[0][1]) print(n_list[1][3]) # Ошибка! Для индексации используются только целочисленные значения print(my_list[4.0])

Вывод:

п
o
а
ч
5
Traceback (most recent call last): 
File "", line 21, in
TypeError: list indices must be integers or slices, not float
2. По отрицательному индексу

Python поддерживает отрицательные индексы в последовательностях. Индекс -1 указывает на последний элемент, -2 — на предпоследний и т. д.

# Отрицательные индексы в списках my_list = ['п', 'р', 'о', 'б', 'а'] print(my_list[-1]) print(my_list[-5])

Вывод:

Срезы списков

С помощью оператора среза : можно получить диапазон элементов в списке.

my_list = ['c', 'o' , 'd', 'e', 'c', 'h', 'i', 'c', 'k'] # элементы с 3 по 5 print(my_list[2:5]) # элементы с 1 по 4 print(my_list[:-5]) # элементы с 6 по последний print(my_list[5:]) # элементы с первого по последний print(my_list[:])
Вывод:
['d', 'e', 'c']
['c','o,'d','e']
['h','i','c','k']
['c','o,'d','e','c','h','i','c','k']

Как изменять элементы в списке

Список — изменяемый тип данных, его элементы можно изменять в отличие от строки или кортежа.

Чтобы изменить один или несколько элементов, можно воспользоваться оператором присваивания = .

Допустим, у нас есть список, который называется odd (нечётные числа). Но в нём почему-то хранятся четные числа. Давайте это исправим.

odd = [2, 4, 6, 8] # изменяем 1-й элемент odd[0] = 1 print(odd) # изменяем элементы со второго по 4 odd[1:4] = [3, 5, 7] print(odd) 

Вывод:

[1, 4, 6, 8]
[1, 3, 5, 7]

Как добавлять элементы в список

Один элемент в список добавляется с помощью метода append() , а несколько — с помощью метода extend() .

odd = [1, 3, 5] odd.append(7) print(odd) odd.extend([9, 11, 13]) print(odd)

Вывод:

[1, 3, 5, 7]

[1, 3, 5, 7, 9, 11, 13]

Для объединения двух списков используется оператор + . Это называется конкатенацией списков.

Оператор * повторяет список заданное количество раз.

odd = [1, 3, 5] print(odd + [9, 7, 5]) print(["re"] * 3)

Вывод:

[1, 3, 5, 9, 7, 5]
['re', 're', 're']

С помощью метода insert() можно вставить один элемент по данному индексу, а присвоив их пустому срезу — несколько.

odd = [1, 9] odd.insert(1,3) print(odd) odd[2:2] = [5, 7] print(odd)

Вывод:

[1, 3, 9]
[1, 3, 5, 7, 9]

Как удалять элементы из списка

Один или несколько элементов списка можно удалить с помощью ключевого слова del . С помощью него можно удалить и весь список.

my_list = ['п', 'р', 'o', 'б', 'л', 'е', 'м', 'а'] # удаление одного элемента del my_list[2] print(my_list) # удаление среза элементов del my_list[1:5] print(my_list) # удаление всего списка del my_list # этот вызов приведет к ошибке # список не определен, т. к. мы удалили его print(my_list)

Вывод:

['п', 'р', 'б', 'л', 'е', 'м', 'а']
['п', 'м', 'а']
Traceback (most recent call last):
File "", line 18, in
NameError: name 'my_list' is not defined

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

Метод pop() удаляет и возвращает последний элемент из списка, если не указан индекс. Это помогает применять списки как стек (структура данных, которая подчиняется принципу LIFO: «последним пришел — первым вышел»).

Для очистки списка используется метод clear() .

my_list = ['п', 'р', 'o', 'б', 'л', 'е', 'м', 'а'] my_list.remove('п') # Вывод: ['р', 'o', 'б', 'л', 'е', 'м', 'а'] print(my_list) # Вывод: 'o' print(my_list.pop(1)) # Вывод: ['р', 'б', 'л', 'е', 'м', 'а'] print(my_list) # Вывод: 'м' print(my_list.pop()) # Вывод: ['р', 'б', 'л', 'е', 'а'] print(my_list) my_list.clear() # Вывод: [] print(my_list)

Вывод:

['р', 'o', 'б', 'л', 'е', 'м', 'а']
o
['р', 'б', 'л', 'е', 'м', 'а']
м
['р', 'б', 'л', 'е', 'а']
[]

Наконец, мы можем удалять элементы из списка, присвоив пустой список срезу элементов.

>>> my_list = ['п', 'р', 'o', 'б', 'л', 'е', 'м', 'а'] >>> my_list[2:3] = [] >>> my_list ['п', 'р', 'б', 'л', 'е', 'м', 'а'] >>> my_list[2:5] = [] >>> my_list ['п', 'р', 'м', 'а']

Методы списков

Методы списков перечислены в таблице ниже. Их нужно использовать с помощью конструкции список.метод() . Некоторые из них мы уже использовали.

Название метода

Что делает

Добавляет элемент в конец списка

Добавляет все элементы списка в другой список

Вставляет элемент по данному в качестве аргумента индексу

Удаляет элемент из списка

Удаляет элемент из списка и возвращает его

Удаляет все элементы из списка

Возвращает индекс первого совпавшего элемента

Считает количество элементов в списке, совпадающих с переданным аргументом

Сортирует элементы в списке в порядке возрастания

Возвращает неглубокую копию списка

# Методы списков my_list = [3, 8, 1, 6, 0, 8, 4] # Вывод: 1 print(my_list.index(8)) # Вывод: 2 print(my_list.count(8)) my_list.sort() # Вывод: [0, 1, 3, 4, 6, 8, 8] print(my_list) my_list.reverse() # Вывод: [8, 8, 6, 4, 3, 1, 0] print(my_list)

Вывод:

1
2
[0, 1, 3, 4, 6, 8, 8]
[8, 8, 6, 4, 3, 1, 0]

Представления списков

Представление списков — элегантный и лаконичный способ создать новый список из существующего.

Представление списков состоит из выражения, за которым следует оператор for , и эта конструкция заключается в квадратные скобки [] .

Давайте создадим список степеней двойки от 1 до 9. Используем для это представление списка.

pow2 = [2 ** x for x in range(10)] print(pow2)

Вывод:

[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

То же самое можно сделать и так:

pow2 = [] for x in range(10): pow2.append(2 ** x)

Но так — длинее. Представление списков более элегантный способ.

В представлениях списков может быть больше операторов for и if . Оператор if он позволяет отфильтровать элементы для нового списка. Он необязателен.

>>> pow2 = [2 ** x for x in range(10) if x > 5] >>> pow2 [64, 128, 256, 512] >>> odd = [x for x in range(20) if x % 2 == 1] >>> odd [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] >>> [y+x for x in ['Python ','C '] for y in ['Язык','Программирование на']] ['Язык Python', 'Программирование на Python', 'Язык C', 'Программирование на C']

Другие операции со списками

Проверка на вхождение элемента в список

С помощью ключевого слова in можно узнать, есть элемент в списке или нет.

my_list = ['п', 'р', 'o', 'б', 'л', 'е', 'м', 'а'] # Вывод: True print('п' in my_list) # Вывод: False print('у' in my_list) # Вывод: True print('с' not in my_list)

Вывод:

True
False
True
Итерирование по списку

С помощью цикла for можно пройтись по каждому элементу в списке.

for fruit in ['яблоки','бананы','манго']: print("Я люблю",fruit)

Вывод:

Я люблю яблоки
Я люблю бананы
Я люблю манго

СodeСhick.io — простой и эффективный способ изучения программирования.

2023 © ООО «Алгоритмы и практика»

Как можно разбить список на вложенные списки, содержащие одинаковые идущие подряд элементы?

Как можно разбить список на вложенные списки, включающие в себя одинаковые элементы, идущие подряд? Если подряд идущих равных элементов нет, необходимо создать вложенный список, содержащий только этот один элемент. Что-то вроде: Было: array = [4, 2, 2, 4, 5, 5, 5, 1, 6, 9, 9, 2] Стало: array = [[4] [2, 2] [4] [5, 5, 5] [1] [6] [9, 9] [2]] Как можно реализовать подобное? Заранее спасибо.

Отслеживать
52.2k 11 11 золотых знаков 108 108 серебряных знаков 312 312 бронзовых знаков
задан 17 апр 2017 в 20:01
limitedeternity limitedeternity
385 2 2 серебряных знака 16 16 бронзовых знаков

4 ответа 4

Сортировка: Сброс на вариант по умолчанию

Можно воспользоваться модулем itertools . Конкретнее, функцией groupby() :

from itertools import groupby array = [4, 2, 2, 4, 5, 5, 5, 1, 6, 9, 9, 2] array = groupby(array) # получаем элемент groupby new_array = [] for elem, grouper in array: new_array.append(list(grouper)) # если не проводить преобразование в какой-либо тип данных # получим itertools._grouper object at MemoryAdress in HEX print(new_array) # [[4], [2, 2], [4], [5, 5, 5], [1], [6], [9, 9], [2]] 

Также, чтобы сократить строки кода можно прибегнуть к конструкции list comprehension . Тогда всё уместится в одну строку, не считая импорта и объявления списка array :

from itertools import groupby array = [4, 2, 2, 4, 5, 5, 5, 1, 6, 9, 9, 2] new_array = [list(grouper) for elem, grouper in groupby(array)] # применяя такую конструкцию, мы можем обновить ссылку: # array = [list(grouper) for elem, grouper in groupby(array)] 

Как выпрямить (flatten) список в Python

Списки в Python используются постоянно, а иногда приходится работать с вложенными списками. В этой статье даны некоторые способы выравнивания (flatten) списков, когда вложенные списки выводят на один уровень вверх.

В чем заключается проблема

Возможно вы встречали такого рода вложенные списки (list), т.е. такие списки, которые сами содержат списки. А ваша задача вынести вложенные элементы в один единственный список. Например, исходный список в Python такой:

groups = [['Hong', 'Ryan'], ['Andry', 'Ross'], ['Mike', 'Smith']]

Нужно его преобразовать следующим образом:

['Hong', 'Ryan', 'Andry', 'Ross', 'Mike', 'Smith']

Задача сводится к выравниванию списка на один уровень. С другой стороны, распаковка списка, который содержит список, который в свою очередь также содержит список и т.д. подразумевает распаковку на n-й уровень, где n — уровень вложенности.

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

Выравнивание с помощью циклов for

Самый простой способ — это использование цикла for. Мы можем пройтись по каждому уровню, чтобы достать вложенные списки. Получается это таким образом (для двухуровневого):

names = [] for group in groups: for name in group: names.append(name)

У объекта list есть метод extend , который принимает на вход итерируемый объект и добавляет его элемент к вызывающему списку:

names = [] for group in groups: names.extend(group)

Подготовка данных для Data Mining на Python

Код курса
DPREP
Ближайшая дата курса

по запросу

Длительность обучения
32 ак.часов
Стоимость обучения
66 000 руб.

Так, мы визуально избавляемся от вложенных циклов, тем самым соблюдая принцип Python: Flat is better than nested. Вместо extend мы можем использовать обычное сложение: сумма двух списков дает один список. Поэтому код переписать можно так:

names = [] for group in groups: names += group

А ещё мы можем воспользоваться list comprehension, о котором мы говорили тут. Он позволяет немного подсократить код. Код на Python с использованием list comprehension выглядит так:

names = [name for group in groups for name in group]

Можно ли использовать * в list comprehension?

В статье мы говорили об операторе * . Он предназначен для распаковки итерируемых объектов. Вот пример того, как его можно использовать:

>>> numbers = [3, 4, 7] >>> more_numbers = [2, 1, *numbers, 11, 18] >>> more_numbers [2, 1, 3, 4, 7, 11, 18]

Можем ли мы использовать данный оператор для распаковки итерируемых объектов внутри list comprehension? Ответ — нет.

>>> names = [*group for group in groups] SyntaxError: iterable unpacking cannot be used in comprehension

Python был лишен данной возможности из-за проблем с читаемостью такого кода (см. PEP448).

Можно ли использовать Python-функцию sum?

Существует ещё трюк для разворачивания списка. И он не самый очевидный и подразумевает использование функции sum :

names = sum(groups, [])

Поскольку данный способ контринтуитивен, мы не рекомендуем его использовать. К тому же, он очень медленный.

Модуль itertools на все времена

Модуль itertools имеет целый набор различных классов и функций, которые предназначены для работы с итерируемыми объектами. Одним из таких классов является chain , который принимает на вход любое количество итерируемых аргументов и возвращает iterator . Этот iterator представляет собой цепочку переданных аргументов. Пример разворачивания списка Python с помощью chain :

>>> from itertools import chain >>> chain(*groups) >>> list(chain(*groups)) ['Hong', 'Ryan', 'Anthony', 'Wilhelmina', 'Margaret', 'Adrian']

Класс chain имеет специальный метод, который не требует предварительной распаковки:

list(chain.from_iterable(groups))

Мы рекомендуем использовать именно этот способ, поскольку он работает быстрее.

Больше подробностей о работе с различными структурами данных вы узнаете на наших образовательных курсах в лицензированном учебном центре обучения и повышения квалификации руководителей и ИТ-специалистов (менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data) в Москве:

  • FUNP: Основы языка Python для анализа данных и решения задач машинного обучения
  • DPREP: Подготовка данных для Data Mining на Python
  • PYML: Машинное обучение на Python
  1. https://treyhunner.com/2021/11/how-to-flatten-a-list-in-python/
  2. https://docs.python.org/3/library/itertools.html#itertools.chain

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *