Наталья Кайда 08 декабря 2022

🐍 Самоучитель по Python для начинающих. Часть 7: Методы работы с кортежами

Кортежи по функциональности похожи на списки – разберемся, когда стоит использовать кортежи вместо списков, и как обрабатывать содержащиеся в них данные. В конце статьи – 10 задач для тренировки.
🐍 Самоучитель по Python для начинающих. Часть 7: Методы работы с кортежами

Кортежи 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)

    

Подведем итоги

Кортежи во многом похожи на списки. Выбор в пользу кортежей стоит делать тогда, когда необходимо защитить данные от случайного изменения. Кроме того, многие операции с кортежами выполняются быстрее и занимают меньше памяти. В следующей статье будем изучать множества.

Содержание самоучителя

  1. Особенности, сферы применения, установка, онлайн IDE
  2. Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
  3. Типы данных: преобразование и базовые операции
  4. Методы работы со строками
  5. Методы работы со списками и списковыми включениями
  6. Методы работы со словарями и генераторами словарей
  7. Методы работы с кортежами
  8. Методы работы со множествами
  9. Особенности цикла for
  10. Условный цикл while
  11. Функции с позиционными и именованными аргументами
  12. Анонимные функции
  13. Рекурсивные функции
  14. Функции высшего порядка, замыкания и декораторы
  15. Методы работы с файлами и файловой системой
  16. Регулярные выражения
  17. Основы скрапинга и парсинга
  18. Основы ООП: инкапсуляция и наследование
  19. Основы ООП – абстракция и полиморфизм
  20. Графический интерфейс на Tkinter
  21. Основы разработки игр на Pygame
  22. Основы работы с SQLite
  23. Основы веб-разработки на Flask
  24. Основы работы с NumPy
  25. Основы анализа данных с Pandas

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ