🐍 Самоучитель по Python для начинающих. Часть 7: Методы работы с кортежами
Кортежи по функциональности похожи на списки – разберемся, когда стоит использовать кортежи вместо списков, и как обрабатывать содержащиеся в них данные. В конце статьи – 10 задач для тренировки.
Кортежи tuple
в Python предназначены, как и списки, для хранения последовательностей, состоящих из данных любого типа. Однако, в отличие от списков, кортежи относятся к неизменяемым типам данных. По этой причине в них часто хранят информацию, которую необходимо защитить от случайного изменения – например, конфигурационные данные.
Кортеж в Питоне: свойства и особенности
1. Кортежи не поддерживают добавление и удаление элементов, но допускают расширение и дополнение для тех элементов, которые относятся к изменяемым типам (списки, словари), а также любые операции с элементами элементов:
>>> numbers = ([1, 2, 3, 4], [5, 4, 5]) >>> numbers[1].extend([3, 5, 9]) >>> numbers[0].append([7, 7, 8]) >>> numbers[1][1] += 5 >>> print(numbers) ([1, 2, 3, 4, [7, 7, 8]], [5, 9, 5, 3, 5, 9])
2. Кортежи поддерживают неограниченный уровень вложенности:
numbers = ((4, 5, 8, (5, 1, (5, 3))), (7, 2, (4, 5, (3, 1, 1))))
3. Кортежи работают немного быстрее, чем списки – это связано с особенностями хранения tuple
в памяти:
>>> from timeit import timeit >>> times = 1000000 >>> t1 = timeit("list(['груша', 'виноград','яблоко', 'банан', 'апельсин'])", number=times) >>> t2 = timeit("tuple(('груша', 'виноград','яблоко', 'банан', 'апельсин'))", number=times) >>> diff = "{:.0%}".format((t2 - t1)/t1) >>> print(f'Время копирования списка {times} раз: {t1}') Время копирования списка 1000000 раз: 0.5761922669999961 >>> print(f'Время копирования кортежа {times} раз: {t2}') Время копирования кортежа 1000000 раз: 0.22475764600000048 >>> print(f'Разница: {diff}') Разница: -61%
4. Кортежи занимают меньше места в памяти:
>>> from sys import getsizeof >>> numbers1 = ((1, 2, 3, 4), (5, 4, 5)) >>> numbers2 = [[1, 2, 3, 4], [5, 4, 5]] >>> print(getsizeof(numbers1)) 36 >>> print(getsizeof(numbers2)) 44
5. Кортежи поддерживают конкатенацию +
и повторение * n
:
>>> num1 = (1, 2, 3) >>> num2 = (4, 5, 6) >>> print(num1 + num2) (1, 2, 3, 4, 5, 6) >>> print(num1 * 3) (1, 2, 3, 1, 2, 3, 1, 2, 3)
6. Элементы tuple
можно использовать в качестве значений переменных; этот прием называют распаковкой кортежа:
>>> seasons = ('весна', 'лето', 'осень', 'зима') >>> s1, s2, s3, s4 = seasons >>> print(s1, s3) весна осень
Создание tuple в Питоне
Пустой кортеж можно создать двумя способами – с помощью круглых скобок ()
и с использованием функции tuple()
:
my_tuple = () my_tuple2 = tuple()
При создании кортежа с одним элементом после этого элемента необходимо ставить запятую, иначе Python не определяет конструкцию как кортеж:
>>> my_tuple = (5) >>> print(type(my_tuple)) <class 'int'> >>> my_tuple = (5,) >>> print(type(my_tuple)) <class 'tuple'>
Создать кортеж с несколькими элементами можно следующими способами.
Способ 1: Перечисление элементов
Как и в случае со списками и словарями, кортеж с данными можно создать вручную. Кортеж может содержать данные различных типов:
info = ('Егор', 'разработчик', 350000, 28)
Элементы кортежа необязательно перечислять в круглых скобках – когда Python получает более одного значения для переменной, создание ("упаковка") кортежа происходит автоматически:
>>> letters = 'a', 'b', 'c', 'd' >>> print(letters) ('a', 'b', 'c', 'd')
Способ 2: Преобразование других типов данных
С помощью встроенной функции tuple()
можно создать кортеж из списка, строки или множества:
>>> my_lst = [4, 6, 2, 8] >>> print(tuple(my_lst)) (4, 6, 2, 8) >>> my_str = 'Я изучаю Python' >>> print(tuple(my_str)) ('Я', ' ', 'и', 'з', 'у', 'ч', 'а', 'ю', ' ', 'P', 'y', 't', 'h', 'o', 'n') >>> my_set = {2, 5, 6, 7} >>> print(tuple(my_set)) (2, 5, 6, 7)
Однако при подобном преобразовании словаря в кортеж останутся только ключи:
>>> my_dict = {'яблоки': 52, 'апельсины': 35} >>> print(tuple(my_dict)) ('яблоки', 'апельсины')
Число напрямую преобразовать в кортеж нельзя:
>>> num = 178394 >>> print(tuple(num)) Traceback (most recent call last): File "<pyshell>", line 1, in <module> TypeError: 'int' object is not iterable
Но если конвертировать число в строку, преобразование пройдет без ошибок:
>>> num = 31232534 >>> print(tuple(str(num))) ('3', '1', '2', '3', '2', '5', '3', '4')
В ходе преобразования строки в кортеж с помощью одной лишь функции tuple()
строка разбивается на отдельные символы. Если нужно разбить строку по одному разделителю, подойдет метод partition()
:
>>> st = 'Я изучаю***Python' >>> print(st.partition('***')) ('Я изучаю', '***', 'Python')
Чтобы разбить строку по всем разделителям, вместе с tuple()
используют split()
:
>>> st = tuple(input().split()) Код на языке Python >>> print(st) ('Код', 'на', 'языке', 'Python')
Способ 3: Генератор кортежей
Генераторы кортежей, в отличие от списков и словарей, не слишком удобно использовать для решения практических задач:
>>> my_tuple = (i for i in range(5)) >>> print(my_tuple) <generator object <genexpr> at 0x023B5830>
Но если генератор кортежа все-таки необходимо использовать, это можно сделать двумя способами:
1. Распаковать сгенерированный объект при выводе:
>>> numbers = (i for i in range(10)) >>> print(*numbers) 0 1 2 3 4 5 6 7 8 9
2. Либо использовать в генераторе функцию tuple()
:
>>> my_tuple = tuple(i ** 2 for i in range(1, 12, 2)) >>> print(my_tuple) (1, 9, 25, 49, 81, 121)
Способ 4: Распаковка строк и списков
Оператор распаковки *
и запятая после имени переменной автоматически превращают строки и списки в кортежи:
>>> st = 'Я изучаю Python' >>> sp = ['Python', 'HTML5', 'CSS', 'JavaScript'] >>> tuple1 = (*st,) >>> tuple2 = (*sp,) >>> print(tuple1) ('Я', ' ', 'и', 'з', 'у', 'ч', 'а', 'ю', ' ', 'P', 'y', 't', 'h', 'o', 'n') >>> print(tuple2) ('Python', 'HTML5', 'CSS', 'JavaScript')
Методы кортежей Python
Кортежи поддерживают большинство методов списков, за исключением удаления элементов и присваивания им новых значений:
>>> my_tuple = (4, 5, 6) >>> del my_tuple[1] Traceback (most recent call last): File "<pyshell>", line 1, in <module> TypeError: 'tuple' object doesn't support item deletion >>> my_tuple[2] = 9 Traceback (most recent call last): File "<pyshell>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
Индексация и срезы
Индексация и срезы в кортежах работают так же, как и в списках:
>>> my_tuple = ('банан', 'груша', 'манго') >>> print(my_tuple[0], my_tuple[-1]) банан манго >>> print(my_tuple[1:]) ('груша', 'манго') >>> print(my_tuple[::-1]) ('манго', 'груша', 'банан')
Для возвращения индексa элемента используется index()
:
>>> nutr = ('белки', 'жиры', 'углеводы') >>> print(nutr.index('белки')) 0
Длина, сумма, минимальный и максимальный элементы
Эти методы тоже аналогичны списочным:
>>> my_tuple = ('карандаш', 'ручка', 'шар') >>> print(len(my_tuple)) 3 >>> print(min(my_tuple, key=len)) шар >>> print(max(my_tuple, key=len)) карандаш >>> nums = (4, 5, 2, 1, 6) >>> print(sum(nums)) 18
Принадлежность
С помощью операторов in
и not in
можно убедиться в наличии (отсутствии) определенного значения в кортеже:
>>> nums = (1, 3, 5, 6, 7, 8) >>> (5 in nums) True >>> (25 not in nums) True
Подсчет элементов
Для подсчета числа вхождений какого-либо значения в кортеже используется count()
:
>>> cities = ('Москва', 'Ростов', 'Москва', 'Рязань', 'Саратов', 'Москва') >>> print(cities.count('Москва')) 3
Сортировка
Кортежи поддерживают сортировку, однако результатом будет список:
>>> nums = (4, 1, 7, 2, 0, 9, 5) >>> print(sorted(nums)) [0, 1, 2, 4, 5, 7, 9]
Если результат должен сохраняться в виде кортежа, нужно использовать tuple()
:
>>> nums = (4, 1, 7, 2, 0, 9, 5) >>> print(tuple(sorted(nums, reverse=True))) (9, 7, 5, 4, 2, 1, 0)
Преобразование кортежей в другие типы данных
Кортеж можно преобразовать в строку:
>>> letters = ('P', 'y', 't', 'h', 'o', 'n') >>> print('*'.join(letters)) P*y*t*h*o*n
В список:
>>> sp = (2, 7, 5, 8, 1) >>> print(list(sp)) [2, 7, 5, 8, 1]
В словарь (если кортеж вложенный и состоит из пар значений):
>>> info = (('фрукты', 5), ('овощи', 15), ('конфеты', 3)) >>> print(dict(info)) {'фрукты': 5, 'овощи': 15, 'конфеты': 3}
Во множество:
>>> numbers = (3, 2, 1, 6, 7, 2, 2, 9) >>> print(set(numbers)) {1, 2, 3, 6, 7, 9}
Сравнение кортежей
Как и списки, кортежи с однородными данными можно сравнивать между собой с помощью операторов >
, >=
, <
, <=
, ==
, !=
. Если элементы кортежей принадлежат к разным типам данных, поддерживаются только операторы ==
и !=
.
>>> tuple1 = (1, 2, 3) >>> tuple2 = (4, 5, 6) >>> print(tuple1 < tuple2) True >>> print(tuple1 != tuple2) True
Практика
Задание 1
Напишите программу, которая:
- Создает кортежи из положительных и отрицательных целых чисел на основе полученной от пользователя строки.
- Выводит количество положительных и отрицательных чисел в этих кортежах.
Пример ввода:
45 -6 -9 43 23 5 2 -9 -1 6 3
Вывод:
Кортеж (45, 43, 23, 5, 2, 6, 3) состоит из 7 положительных чисел Кортеж (-6, -9, -9, -1) состоит из 4 положительных чисел
Решение:
numbers = tuple(map(int, input().split())) pos = tuple(i for i in numbers if i > 0) neg = tuple(i for i in numbers if i < 0) print(f'Кортеж {pos} состоит из {len(pos)} положительных чисел') print(f'Кортеж {neg} состоит из {len(neg)} положительных чисел')
Задание 2
Напишите программу, которая:
- Создает кортеж из полученной от пользователя строки, состоящей из вещественных чисел, разделенных пробелами.
- Выводит минимальный и максимальный элементы кортежа, а также их сумму.
Пример ввода:
3.45 6.78 8.99 1.45 4.32 19.04 0.55
Вывод:
Минимальное число: 0.55 Максимальное число: 19.04 Сумма min и max: 19.59
Решение:
my_tuple = tuple(map(float, input().split())) print(f'Минимальное число: {min(my_tuple)}') print(f'Максимальное число: {max(my_tuple)}') print(f'Сумма min и max: {((min(my_tuple) + max(my_tuple))):.2f}')
Задание 3
Имеется кортеж списков, в которых перечислены названия фруктов и калорийность:
fruit = (['яблоки', 46], ['персики', 49], ['лимоны', 36], ['виноград', 190])
Калорийность винограда указана ошибочно. Напишите программу, которая исправит калорийность на 75
, и добавит в третий элемент кортежа новое значение ['айва', 42]
. Результат должен выглядеть так:
fruit = (['яблоки', 46], ['персики', 49], ['лимоны', 36, 'айва', 42], ['виноград', 75])
Решение:
fruit = (['яблоки', 46], ['персики', 49], ['лимоны', 36], ['виноград', 190]) fruit[3][1] = 75 fruit[2].extend(['айва', 42]) print(fruit)
Задание 4
Имеется вложенный кортеж:
numbers = ((5, 4, 5, 4), (3, 3, 4, 6), (8, 9, 5, 4), (12, 4, 5, 1), (9, 3, 5, 1))
Напишите программу, которая формирует новый кортеж, состоящий из средних арифметических значений элементов numbers
. Результат выводится в следующем виде:
4.5 4.0 6.5 5.5 4.5
Решение:
numbers = ((5, 4, 5, 4), (3, 3, 4, 6), (8, 9, 5, 4), (12, 4, 5, 1), (9, 3, 5, 1)) avg = tuple(sum(i)/len(i) for i in numbers) print(*avg)
Задание 5
Имеется вложенный кортеж:
nested_tuple = ((12, 3, 1), (5, 11), (15, 7, 8, 9), (10, 6, 4))
Напишите программу для преобразования nested_tuple в обычный кортеж, упорядоченный по возрастанию:
(1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15)
Решение:
nested_tuple = ((12, 3, 1), (5, 11), (15, 7, 8, 9), (10, 6, 4)) res = [] flat_list = [res.extend(i) for i in nested_tuple] print(tuple(sorted(res)))
Задание 6
Напишите программу для сортировки вложенного кортежа по третьему элементу. Исходный кортеж:
(('красный', 33, 55), ('зеленый', 17, 44), ('синий', 12, 3), ('черный', 2, 5))
Результат:
(('черный', 2, 5), ('синий', 12, 3), ('зеленый', 17, 44), ('красный', 33, 55))
В качестве ключа сортировки следует использовать конструкцию key=lambda x: x[2]
– это анонимная функция. В последующих статьях мы будем подробно разбирать применение анонимных функций.
Решение:
nested_tuple = (('красный', 33, 55), ('зеленый', 17, 44), ('синий', 12, 3), ('черный', 2, 5)) nested_tuple = tuple(sorted(list(nested_tuple), key=lambda x: x[2])) print(nested_tuple)
Задание 7
Напишите программу, которая:
- принимает на вход строку, состоящую из цифр или символов, разделенных пробелами;
- создает из строки кортеж;
- проверяет, состоит ли кортеж из одинаковых элементов;
- выводит
True
илиFalse
в зависимости от результатов проверки.
Для проверки соответствия всех элементов одному условию в Python используется встроенная функция all():
all(i == my_tuple[0] for i in my_tuple)
Пример ввода:
35 35 35 35 35
Вывод:
True
Решение:
my_tuple = tuple(input().split()) print(all(i == my_tuple[0] for i in my_tuple))
Задание 8
Напишите программу, которая на основе исходного кортежа создает новый кортеж, из которого исключены все пользователи с номерами телефонов с региональным кодом +56.
Исходный кортеж:
info = (('Евгений Романов', 25, '+56(983)354-67-21'), ('Марина Дятлова', 22, '+56(190)251-45-79'), ('Кирилл Кудрявцев', 34, '+7(890)456-12-42'), ('Сергей Дятлов', 24, '+56(190)156-42-99'), ('Юлия Степанова', 21, '+16(398)355-33-09'), ('Тимофей Иванов', 34, '+7(918)222-52-77'))
Ожидаемый результат:
(('Кирилл Кудрявцев', 34, '+7(890)456-12-42'), ('Юлия Степанова', 21, '+16(398)355-33-09'), ('Тимофей Иванов', 34, '+7(918)222-52-77'))
Решение:
info = (('Евгений Романов', 25, '+56(983)354-67-21'), ('Марина Дятлова', 22, '+56(190)251-45-79'), ('Кирилл Кудрявцев', 34, '+7(890)456-12-42'), ('Сергей Дятлов', 24, '+56(190)156-42-99'), ('Юлия Степанова', 21, '+16(398)355-33-09'), ('Тимофей Иванов', 34, '+7(918)222-52-77')) new_info = tuple([i for i in info if not i[2].startswith('+56')]) print(new_info)
Задание 9
Имеется кортеж списков:
numbers = ([4, 5], [4, 5], [1, 6], [7, 3], [3, 3], [2, 4], [9, 5], [1, 1])
Напишите программу, которая добавит цифру 5
в конец каждого списка.
Ожидаемый результат:
numbers = ([4, 5, 5], [4, 5, 5], [1, 6, 5], [7, 3, 5], [3, 3, 5], [2, 4, 5], [9, 5, 5], [1, 1, 5])
Решение:
numbers = ([4, 5], [4, 5], [1, 6], [7, 3], [3, 3], [2, 4], [9, 5], [1, 1]) add = [i.extend([5]) for i in numbers] print(numbers)
Задание 10
Напишите программу, которая:
- получает на вход целое число n – количество точек на плоскости;
- получает n строк с координатами
x, y
; - определяет точку, наиболее удаленную от начала координат.
Пример ввода:
5 4 8 1 2 7 4 7 8 3 2
Вывод:
7 8
Решение:
n = int(input()) points = [tuple(map(int, input().split())) for i in range(n)] mx = max(points, key=lambda x: x[0] ** 2 + x[1] ** 2) print(*mx)
Подведем итоги
Кортежи во многом похожи на списки. Выбор в пользу кортежей стоит делать тогда, когда необходимо защитить данные от случайного изменения. Кроме того, многие операции с кортежами выполняются быстрее и занимают меньше памяти. В следующей статье будем изучать множества.
Содержание самоучителя
- Особенности, сферы применения, установка, онлайн IDE
- Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
- Типы данных: преобразование и базовые операции
- Методы работы со строками
- Методы работы со списками и списковыми включениями
- Методы работы со словарями и генераторами словарей
- Методы работы с кортежами
- Методы работы со множествами
- Особенности цикла for
- Условный цикл while
- Функции с позиционными и именованными аргументами
- Анонимные функции
- Рекурсивные функции
- Функции высшего порядка, замыкания и декораторы
- Методы работы с файлами и файловой системой
- Регулярные выражения
- Основы скрапинга и парсинга
- Основы ООП: инкапсуляция и наследование
- Основы ООП – абстракция и полиморфизм
- Графический интерфейс на Tkinter
- Основы разработки игр на Pygame
- Основы работы с SQLite
- Основы веб-разработки на Flask
- Основы работы с NumPy
- Основы анализа данных с Pandas