Методы работы со списками и списковыми включениями
Рассмотрим методы, которые чаще всего используются для обработки списков, и покажем, как легко можно решать разнообразные задачи с помощью списковых включений.
Список в Python – это структура данных для хранения последовательности, состоящей из чисел, строк, отдельных символов. Такие последовательности могут быть как однородными (состоящими из данных одного типа), так и смешанными:
my_list1 = [1, 2, 3, 4, 5]
my_list2 = ['P', 'y', 't', 'h', 'o', 'n']
my_list3 = ['адрес', 'телефон', 'имя']
my_list4 = ['Евгений', 23, 'разработчик', 1.77]
Значения, из которых состоит список, называются элементами списка. К элементам списка можно обращаться по индексам (нумерация, как и в случае со строками, всегда начинается с 0), отрицательная нумерация также поддерживается:
>>> my_lst = ['P', 'y', 't', 'h', 'o', 'n']
>>> print(my_lst[2])
t
>>> print(my_lst[-3])
h
Как и при работе со строками, для операций со списками можно использовать срезы:
>>> lst = [1, 3, 2, 4, 5]
>>> print(lst[::-1])
[5, 4, 2, 3, 1]
>>> print(lst[1:4])
[3, 2, 4]
Списки аналогичны массивам в других языках программирования. Списки бывают одномерными и многомерными – на практике чаще всего встречаются двумерные (матрицы):
matrix = [[2, 4, 6, 8, 10], [3, 6, 9, 12, 15], [4, 8, 12, 16, 20]]
matrix2 = [[12, 14, 16, 18, 10],
[13, 16, 19, 12, 15],
[14, 18, 12, 16, 20]]
Индексация элементов в многомерных списках аналогична математической – за исключением того, что нумерация начинается с 0, а не с 1. Для обращения к нужному элементу необходимо указать номер столбца и строки:
>>> lst = [[1, 3, 2], [4, 5, 6], [7, 8, 9], [2, 1, 8], [7, 3, 4]]
>>> print(lst[2][2])
9
Для сложных математических операций с многомерными массивами обычно используют специальную библиотеку NumPy.
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста»
Создание и ввод списков
Есть несколько способов создать список – данные можно ввести вручную, сгенерировать, преобразовать из какого-либо другого типа с помощью встроенных функций list() или split(). Рассмотрим все эти способы подробнее.
Первый способ: указание значений списка вручную
Список с данными создается простым перечислением нужных значений в квадратных скобках []
:
num_list = [5, 15, 25, 0, 6]
symb_list = ['a', 'b', 'c', 'd']
Для создания пустого списка достаточно объявить его название и указать на тип с помощью квадратных скобок или встроенной функции list():
spisok = []
my_lst = list()
Второй способ: преобразование других типов данных в список
Уже упомянутая функция list() позволяет преобразовать строку в список:
>>> my_lst = list('Python')
>>> print(my_lst)
['P', 'y', 't', 'h', 'o', 'n']
При этом list() можно комбинировать с другими функциями. Так можно разделить вводимую строку на отдельные символы:
>>> sp = list(input())
Я изучаю Python
>>> print(sp)
['Я', ' ', 'и', 'з', 'у', 'ч', 'а', 'ю', ' ', 'P', 'y', 't', 'h', 'o', 'n']
Во многих случаях для преобразования строки в список достаточно split():
>>> sp = 'Разработка ПО на языке Python'.split()
>>> print(sp)
['Разработка', 'ПО', 'на', 'языке', 'Python']
С помощью split() можно разбить строку по определенным разделителям – по умолчанию это пробел:
>>> sp = input().split()
Я изучаю методы списков
>>> print(sp)
['Я', 'изучаю', 'методы', 'списков']
Разделитель, отличный от пробела, указывают в одинарных или двойных кавычках:
>>> lst = input().split(';')
номер;модель;цена;количество
>>> print(lst)
['номер', 'модель', 'цена', 'количество']
Использование strip() обеспечивает удаление ненужных пробелов в начале и конце строки, а map() применяет нужную функцию ко всем элементам списка. В приведенном ниже примере map() применяет int() к каждому символу строки, преобразовывая строковые символы в целые числа:
>>> my_lst = list(map(int, input().strip().split()))
3 4 5 2 3 4 5 6 1 2 8
>>> print(my_lst)
[3, 4, 5, 2, 3, 4, 5, 6, 1, 2, 8]
Третий способ: генерация списков
При необходимости список можно сгенерировать. Самый простой метод – использовать встроенную функцию range(), которая обеспечит автоматическое создание списка, включающего значения из определенного диапазона:
>>> my_lst = list(range(5))
>>> print(my_lst)
[0, 1, 2, 3, 4]
>>> my_lst = list(range(1, 25, 2))
>>> print(my_lst)
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23]
Другой метод генерации списка – использование list comprehension (списковое включение). В приведенном ниже примере список создается из четных чисел, входящих в определенный диапазон:
>>> my_lst = [i for i in range(1, 51) if i % 2 == 0]
>>> print(my_lst)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50]
А здесь список составляется из чисел, возведенных в квадрат:
>>> sqr = [i ** 2 for i in range(20)]
>>> print(sqr)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]
Поскольку списковые включения позволяют создавать списки по определенным правилам и условиям, их часто используют в качестве компактной замены циклов for и условий if, которые мы будем рассматривать позже:
>>> my_str = '6emds83mmsad99342n42ld9xm37vn4820'
>>> my_lst2 = [i for i in my_str if i.isnumeric()]
>>> print(my_lst2)
['6', '8', '3', '9', '9', '3', '4', '2', '4', '2', '9', '3', '7', '4', '8', '2', '0']
Вывод и распаковка списка
При стандартном использовании print() элементы выводятся в кавычках (если это строковые данные) и в квадратных скобках. Избавиться от кавычек и скобок поможет оператор распаковки *
:
>>> lst = [1, 2, 3, 4, 5]
>>> lst2 = ['a', 'b', 'c', 'd', 'e']
>>> print(*lst)
1 2 3 4 5
>>> print(*lst2)
a b c d e
Для вывода в столбик пригодится разделитель /n
:
>>> my_lst = list('JavaScript')
>>> print(*my_lst, sep='\n')
J
a
v
a
S
c
r
i
p
t
Основные методы списков
Список – очень удобная структура данных, а разнообразие методов работы со списками в Python позволяет легко и элегантно решить любую практическую задачу по хранению и обработке последовательностей. Перечислим самые полезные методы.
Максимальный и минимальный элемент списка – max() и min():
>>> sp = [5, 6, 2, 90, 12, 0, 4, 1, 3]
>>> print(max(sp), min(sp))
90 0
Функции max() и min() могут принимать дополнительные параметры, например, длину key=len
:
>>> lst = ['яблоко', 'апельсин', 'дыня']
>>> print(max(lst, key=len))
апельсин
>>> print(min(lst, key=len))
дыня
Сумма элементов списка – sum():
>>> sp = [5, 3, 2, 1, 9, 0, 7]
>>> print(sum(sp))
27
Сортировка по возрастанию и убыванию – sort() и sort с ключом reverse=True:
>>> lst = [7, 6, 0, 9, 5, 3, 2, 8, 1]
>>> lst.sort()
>>> print(lst)
[0, 1, 2, 3, 5, 6, 7, 8, 9]
>>> lst.sort(reverse=True)
>>> print(lst)
[9, 8, 7, 6, 5, 3, 2, 1, 0]
>>> my_lst = ['яблоко', 'ананас', 'груша']
>>> my_lst.sort()
>>> print(my_lst)
['ананас', 'груша', 'яблоко']
>>> my_lst.sort(reverse=True)
>>> print(my_lst)
['яблоко', 'груша', 'ананас']
Перестановка элементов в обратном порядке – reverse():
>>> lst = ['м', 'о', 'н', 'и', 'т', 'о', 'р']
>>> lst.reverse()
>>> print(lst)
['р', 'о', 'т', 'и', 'н', 'о', 'м']
Добавление элемента append() и расширение списка другим списком – extend():
>>> lst = ['a', 'b', 'c']
>>> lst.append('d')
>>> print(lst)
['a', 'b', 'c', 'd']
>>> lst2 = ['k', 'l', 'm']
>>> lst.extend(lst2)
>>> print(lst)
['a', 'b', 'c', 'd', 'k', 'l', 'm']
Подсчет количества всех элементов списка len() и подсчет определенных элементов count():
>>> lst = ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']
>>> print(len(lst))
11
>>> print(lst.count('a'))
5
Удаление элемента по индексу – del() и по значению – remove():
>>> lst = ['п', 'р', 'о', 'г', 'р', 'а', 'м', 'м', 'а']
>>> del lst[5]
>>> del lst[-1]
>>> print(lst)
['п', 'р', 'о', 'г', 'р', 'м', 'м']
>>> lst.remove('г')
>>> print(lst)
['п', 'р', 'о', 'р', 'м', 'м']
>>> del lst[2:4]
>>> print(lst)
['п', 'р', 'м', 'м']
Удаление и возврат последнего элемента – pop():
>>> lst = ['м', 'о', 'н', 'и', 'т', 'о', 'р']
>>> print(lst.pop())
р
Если указать индекс элемента, он будет удален вместо последнего:
>>> lst = ['н', 'о', 'у', 'т', 'б', 'у', 'к']
>>> lst.pop(3)
'т'
>>> lst.pop(5)
'к'
>>> print(lst)
['н', 'о', 'у', 'б', 'у']
Удаление всех элементов списка – clear():
>>> lst = ['к', 'у', 'р', 'с']
>>> lst.clear()
>>> print(lst)
[]
Вставка элемента в определенную позицию – insert():
>>> lst = ['П', 'т', 'о', 'н']
>>> lst.insert(1, 'а')
>>> lst.insert(2, 'й')
>>> print(lst)
['П', 'а', 'й', 'т', 'о', 'н']
Индекс первого вхождения элемента index() в списке или в диапазоне:
>>> lst = ['н', 'о', 'у', 'т', 'б', 'у', 'к']
>>> print(lst.index('у'))
2
>>> print(lst.index('у', 3, 6))
5
Создание поверхностной копии списка – copy():
>>> lst = [1, 2, 3, [5, 6]]
>>> lst2 = lst.copy()
>>> print(lst2)
[1, 2, 3, [5, 6]]
Объединение элементов списка в строку – join():
Этот метод мы уже рассматривали в предыдущей статье – он относится одновременно и к методам списков, и методам строк:
>>> lst = ['|', '|', '|', '|', '|', '|']
>>> print('***'.join(lst))
|***|***|***|***|***|
>>> print('_'.join(lst))
|_|_|_|_|_|
>>> print(''.join(lst))
||||||
Параллельная обработка списков – zip():
>>> list1 = [3, 4, 1, 2, 7]
>>> list2 = [6, 9, 2, 5, 3]
>>> list3 = [i + j for i, j in zip(list1, list2)]
>>> print(list3)
[9, 13, 3, 7, 10]
Практика
Задание 1
Напишите программу, которая получает на вход строку, выбирает из нее все числа, и выводит:
- минимальное число;
- максимальное число;
- сумму всех чисел.
Пример ввода:
5rff09832ejwfdew09f034
Вывод:
0
9
43
Решение:
lst = [int(i) for i in input() if i.isdigit()]
print(min(lst), max(lst), sum(lst), sep='\n')
Задание 2
Напишите программу, которая:
- получает на вход строку, состоящую из разделенных пробелами числовых символов;
- преобразует символы в целые числа;
- формирует из чисел список, не включая в него цифры, встречающиеся в исходной строке только 1 раз;
- выводит список без скобок.
Пример ввода:
3 4 5 1 2 3 6 7 4 8 9 4 5 6 6
Вывод:
3 4 5 3 6 4 4 5 6 6
Решение:
st = [int(i) for i in input().split()]
lst = [i for i in st if st.count(i) > 1]
print(*lst)
Задание 3
Напишите программу, которая:
- получает на вход строку чисел, разделенных запятыми;
- формирует из чисел два списка – с четными и нечетными числами;
- выводит списки без скобок на отдельных строках.
Примечание: «не равно» в Python обозначается с помощью !=
.
Пример ввода:
3,4,2,7,8,9,1,11,2,56,2,6,81
Вывод:
3 7 9 1 11 81
4 2 8 2 56 2 6
Решение:
st = [int(i) for i in input().split(',')]
lst_odd = [i for i in st if i % 2 != 0]
lst_even = [i for i in st if i % 2 == 0]
print(*lst_odd)
print(*lst_even)
Задание 4
Напишите программу, которая:
- получает на вход слово, в котором одна буква ошибочно повторяется более 2 раз подряд;
- выводит ошибочную букву, число повторов и исправленное слово (если число повторов 1, в противном случае – сообщение
Не могу исправить
.
Гарантируется, что ошибочная буква не встречается в других частях слова, то есть программа будет получать на вход слова типа «коллллектив», а не «комммунизм».
Пример ввода 1:
колллаборация
Вывод:
Буква "л" ошибочно повторяется 1 раз(а)
Исправленное слово: коллаборация
Пример ввода 2:
Дилемммма
Вывод:
Буква "м" ошибочно повторяется 2 раз(а)
Не могу исправить
Примечание: в print() можно использовать условия if и else, например:
print("вариант 1" if i > 5 else "вариант 2")
Решение:
st = list(input())
err = [st.index(i) for i in st if st.count(i) > 2]
letter = st[err[0]]
st.remove(letter)
print(f'Буква "{letter}" ошибочно повторяется {len(err) - 2} раз(а)')
print(f'Исправленное слово: {"".join(st)}' if len(err) == 3 else 'Не могу исправить')
Задание 5
Напишите программу, которая:
- получает на вход строку, содержащую (в любой позиции) символ
#
; - находит и удаляет
#
по индексу; - выводит исправленную строку и ее самое длинное слово.
Пример ввода:
Без труд#а не выловишь и рыбку из пруда
Вывод:
Без труда не выловишь и рыбку из пруда
Выловишь
Решение:
st = list(input())
err = st.index('#')
del st[err]
sp = ''.join(st)
word = max(sp.split(), key=len)
print(sp, word, sep='\n')
Задание 6
Напишите программу, которая:
- принимает на вход строку, состоящую из случайных слов;
- отбрасывает слова, в которых есть небуквенные символы;
- переставляет слова в порядке возрастания;
- выводит на экран слова в столбик, без кавычек.
Пример ввода:
фрукты образцовый груз@вик цветы невз56годы дер#ево задачка виноградник грозовой зима яб7локо
Вывод:
зима
цветы
фрукты
задачка
грозовой
образцовый
виноградник
Решение:
sp = input().split()
sp = [i for i in sp if i.isalpha()]
sp.sort(key=len)
print(*sp, sep='\n')
Задание 7
Напишите программу, которая получает на вход строку, и формирует из нее 2 списка:
- в первый список входят слова, начинающиеся с гласных букв;
- второй список состоит из слов, начинающихся с согласных.
Выведите результат в две строки без кавычек и скобок.
Пример ввода:
кот ёж море ель береза апельсин бирюза имитация
Вывод:
ёж ель апельсин имитация
кот море береза бирюза
Решение:
vowels = 'аиеёоуыэюя'
st = input().split()
lst1 = [i for i in st if i[0] in vowels]
lst2 = [i for i in st if i not in lst1]
print(*lst1)
print(*lst2)
Задание 8
Имеются два списка:
keys = ['модель', 'цена', 'количество', 'размер', 'цвет', 'скидка']
values = ['XXLDude', 5678.00, 57, 'XXL', 'черный', '12%']
Напишите программу, которая объединяет эти списки и выводит на экран список такого вида:
модель: XXLDude
цена: 5678.55
количество: 57
размер: XXL
цвет: черный
скидка: 12%
Решение:
keys = ['модель', 'цена', 'количество', 'размер', 'цвет', 'скидка']
values = ['XXLDude', 5678.55, 57, 'XXL', 'черный', '12%']
res = [key + ': ' + str(value) for key, value in zip(keys, values)]
print(*res, sep='\n')
Задание 9
Напишите программу, которая получает на вход строку, содержащую имя ученика и его отметки по основным предметам, и выводит средний балл успеваемости.
Пример ввода:
Вася Пупкин, 4 5 3 4 5 3 4 5
Вывод:
Вася Пупкин, средний балл: 4.12
Примечание: для вывода двух знаков после запятой в f-строках используется параметр :.2f
.
Решение:
lst = input().split(', ')
grades = [int(i) for i in lst[1].split()]
avg = sum(grades) / len(grades)
print(f'{lst[0]}, средний балл: {avg:.2f}')
Задание 10
Игрушечный робот передвигается в соответствии с командами, получаемыми в виде строки вида n35 s48 e88 w33 n12 s10
, где n – север, s – юг, w – запад, e – восток, а цифры – расстояние в сантиметрах. Напишите программу для определения x и y координат робота. Будем считать, что движение всегда начинается с 0, 0
.
Пример ввода:
n15 e12 s32 e18 w27 n50 s5 e45
Вывод:
x: 48, y: 28
Решение:
route = input().split()
s = sum([int(i[1:]) for i in route if i[0] == 's'])
n = sum([int(i[1:]) for i in route if i[0] == 'n'])
w = sum([int(i[1:]) for i in route if i[0] == 'w'])
e = sum([int(i[1:]) for i in route if i[0] == 'e'])
print(f'x: {e - w}, y: {n - s}')
Подведем итоги
В этой статье мы изучили основные (и самые полезные) методы работы со списками и списковыми включениями. Списковые включения отлично заменяют циклы с условиями и делают код максимально лаконичным. В следующей статье расскажем про методы работы со словарями.