Кортежи (tuple)
Сегодня я расскажу о таком типе данных, как кортежи (tuple) и о том, где они применяются.
Кортеж, по сути — неизменяемый список.
Зачем нужны кортежи, если есть списки?
- Защита от дурака. То есть кортеж защищен от изменений, как намеренных (что плохо), так и случайных (что хорошо).
- Меньший размер. Дабы не быть голословным:
Как работать с кортежами?
С преимуществами кортежей разобрались, теперь встает вопрос — а как с ними работать. Примерно так же, как и со списками.
Создаем пустой кортеж:
Создаем кортеж из одного элемента:
Ну и создать кортеж из итерируемого объекта можно с помощью все той же пресловутой функции tuple()
Операции с кортежами
Все операции над списками, не изменяющие список (сложение, умножение на число, методы index() и count() и некоторые другие операции). Можно также по-разному менять элементы местами и так далее.
Например, гордость программистов на python - поменять местами значения двух переменных:
Для вставки кода на Python в комментарий заключайте его в теги
- Модуль csv - чтение и запись CSV файлов
- Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
- Онлайн-обучение Python: сравнение популярных программ
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов
- Сделай свой вклад в развитие сайта!
- Самоучитель Python
- Карта сайта
- Отзывы на книги по Python
- Реклама на сайте
Кортежи
Кортежи (tuple) в Python – это те же списки за одним исключением. Кортежи неизменяемые структуры данных. Так же как списки они могут состоять из элементов разных типов, перечисленных через запятую. Кортежи заключаются в круглые, а не квадратные скобки.
>>> a = (10, 2.13, "square", 89, 'C') >>> a (10, 2.13, 'square', 89, 'C')
Из кортежа можно извлекать элементы и брать срезы:
>>> a[3] 89 >>> a[1:3] (2.13, 'square')
Однако изменять его элементы нельзя:
>>> a[0] = 11 Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment
Также у типа tuple нет методов для добавления и удаления элементов.
Возникает резонный вопрос. Зачем в язык программирования был введен этот тип данных, по-сути представляющий собой неизменяемый список? Дело в том, что иногда надо защитить список от изменений. Преобразовать же кортеж в список, если это потребуется, как и выполнить обратную операцию легко с помощью встроенных в Python функций list() и tuple() :
>>> a = (10, 2.13, "square", 89, 'C') >>> b = [1, 2, 3] >>> c = list(a) >>> d = tuple(b) >>> c [10, 2.13, 'square', 89, 'C'] >>> d (1, 2, 3)
Рассмотрим случай, когда уместно использовать кортежи. В Python изменяемые объекты передаются в функцию по ссылке. Это значит, что не создается копия объекта, а переменной-параметру присваивается ссылка на уже существующий объект. В итоге, если в теле функции объект изменяется, то эти изменения касаются глобального объекта.
def add_num(seq, num): for i in range(len(seq)): seq[i] += num return seq origin = [3, 6, 2, 6] changed = add_num(origin, 3) print(origin) print(changed)
Данная программа неправильная. Хотя никаких выбросов исключений не произойдет, она содержит логическую ошибку. На выводе получаем:
[6, 9, 5, 9] [6, 9, 5, 9]
То есть исходный список был также изменен. Параметр seq содержал ссылку не на свой локальный список, а на список-оригинал. Таким образом, в операторе return здесь нет смыла. Если функция замысливалась как изменяющая глобальный список, то программа должна выглядеть так:
def add_num(seq, num): for i in range(len(seq)): seq[i] += num origin = [3, 6, 2, 6] add_num(origin, 3) print(origin)
Что делать, если все же требуется не изменять исходный список, а сформировать по нему новый. Задачу можно решить несколькими способами. Во первых, в функции можно создать локальный список, после чего возвращать его:
def add_num(seq, num): new_seq = [] for i in seq: new_seq.append(i + num) return new_seq origin = [3, 6, 2, 6] changed = add_num(origin, 3) print(origin) print(changed)
[3, 6, 2, 6] [6, 9, 5, 9]
Исходный список в функции не меняется. Его элементы лишь перебираются.
Второй способ защитить список-оригинал – использовать кортеж. Этот способ более надежный, так как в больших программах трудно отследить, что ни одна функция не содержит команд изменения глобальных данных.
Хотя преобразовывать к кортежу можно как при передаче в функцию, так и в самой функции, лучше сразу делать глобальный список кортежем. Поскольку неизменяемые объекты передаются по значению, а не по ссылке, то в функцию будет поступать копия структуры, а не оригинал. Даже если туда передается оригинал, изменить его невозможно. Можно лишь, как вариант, скопировать его и/или изменить тип, создав тем самым локальную структуру, и делать с ней все, что заблагорассудится.
def add_num(seq, num): seq = list(seq) for i in range(len(seq)): seq[i] += num return seq origin = (3, 6, 2, 6) changed = add_num(origin, 3) print(origin) print(changed)
Списки в кортежах
Кортежи могут содержать списки, также как списки быть вложенными в другие списки.
>>> nested = (1, "do", ["param", 10, 20])
Как вы думаете, можем ли мы изменить список ["param", 10, 20] вложенный в кортеж nested ? Список изменяем, кортеж – нет. Если вам кажется, что нельзя, то вам кажется неправильно. На самом деле можно:
>>> nested[2][1] = 15 >>> nested (1, 'do', ['param', 15, 20])
Примечание. Выражения типа nested[2][1] используются для обращения к вложенным объектам. Первый индекс указывает на позицию вложенного объекта, второй – индекс элемента внутри вложенного объекта. Так в данном случае сам список внутри кортежа имеет индекс 2, а элемент списка 10 – индекс 1 в списке.
Странная ситуация. Кортеж неизменяем, но мы все-таки можем изменить его. На самом деле кортеж остается неизменяемым. Просто в нем содержится не сам список, а ссылка на него. Ее изменить нельзя. Но менять сам список можно.
Чтобы было проще понять, перепишем кортеж так:
>>> l = ["param", 10, 20] >>> t = (1, "do", l) >>> t (1, 'do', ['param', 10, 20])
Кортеж содержит переменную-ссылку. Поменять ее на другую ссылку нельзя. Но кортеж не содержит самого списка. Поэтому его можно менять как угодно:
>>> l.pop(0) 'param' >>> t (1, 'do', [10, 20])
Однако такой номер не проходит с неизменяемыми типами:
>>> a = "Kat" >>> t = (a, l) >>> t ('Kat', [10, 20]) >>> a = "Bat" >>> t ('Kat', [10, 20])
Они передаются в кортеж как и в функцию – по значению. То есть их значение копируется в момент передачи.
Практическая работа
- Чтобы избежать изменения исходного списка, не обязательно использовать кортеж. Можно создать его копию с помощью метода списка copy() или взять срез от начала до конца [:] . Скопируйте список первым и вторым способом и убедитесь, что изменение копий никак не отражается на оригинале.
- Заполните один кортеж десятью случайными целыми числами от 0 до 5 включительно. Также заполните второй кортеж числами от -5 до 0. Для заполнения кортежей числами напишите одну функцию. Объедините два кортежа с помощью оператора +, создав тем самым третий кортеж. С помощью метода кортежа count() определите в нем количество нулей. Выведите на экран третий кортеж и количество нулей в нем.
Примеры решения и дополнительные уроки в pdf-версии курса
X Скрыть Наверх
Python. Введение в программирование
Что такое кортеж в python
Кортеж (tuple) представляет последовательность элементов, которая во многом похожа на список за тем исключением, что кортеж является неизменяемым (immutable) типом. Поэтому мы не можем добавлять или удалять элементы в кортеже, изменять его.
Для создания кортежа используются круглые скобки, в которые помещаются его значения, разделенные запятыми:
tom = ("Tom", 23) print(tom) # ("Tom", 23)
Также для определения кортежа мы можем просто перечислить значения через запятую без применения скобок:
tom = "Tom", 23 print(tom) # ("Tom", 23)
Если вдруг кортеж состоит из одного элемента, то после единственного элемента кортежа необходимо поставить запятую:
tom = ("Tom",)
Для создания кортежа из другого набора элементов, например, из списка, можно передать список в функцию tuple() , которая возвратит кортеж:
data = ["Tom", 37, "Google"] tom = tuple(data) print(tom) # ("Tom", 37, "Google")
С помощью встроенной функции len() можно получить длину кортежа:
tom = ("Tom", 37, "Google") print(len(tom)) # 3
Обращение к элементам кортежа
Обращение к элементам в кортеже происходит также, как и в списке, по индексу. Индексация начинается также с нуля при получении элементов с начала списка и с -1 при получении элементов с конца списка:
tom = ("Tom", 37, "Google", "software developer") print(tom[0]) # Tom print(tom[1]) # 37 print(tom[-1]) # software developer
Но так как кортеж - неизменяемый тип (immutable), то мы не сможем изменить его элементы. То есть следующая запись работать не будет:
tom[1] = "Tim"
При необходимости мы можем разложить кортеж на отдельные переменные:
name, age, company, position = ("Tom", 37, "Google", "software developer") print(name) # Tom print(age) # 37 print(position) # software developer print(company) # Google
Получение подкортежей
Как и в списках, можно получить часть кортежа в виде другого кортежа
tom = ("Tom", 37, "Google", "software developer") # получем подкортеж с 1 по 3 элемента (не включая) print(tom[1:3]) # (37, "Google") # получем подкортеж с 0 по 3 элемента (не включая) print(tom[:3]) # ("Tom", 37, "Google") # получем подкортеж с 1 по послдений элемент print(tom[1:]) # (37, "Google", "software developer")
Кортеж как параметр и результат функций
Особенно удобно использовать кортежи, когда необходимо возвратить из функции сразу несколько значений. Когда функция возвращает несколько значений, фактически она возвращает в кортеж:
def get_user(): name = "Tom" age = 22 company = "Google" return name, age, company user = get_user() print(user) # ("Tom", 37, "Google")
При передаче кортежа в функцию с помощью оператора * его можно разложить на отдельные значения, которые передаются параметрам функции:
def print_person(name, age, company): print(f"Name: Age: Company: ") tom = ("Tom", 22) print_person(*tom, "Microsoft") # Name: Tom Age: 22 Company: Microsoft bob = ("Bob", 41, "Apple") print_person(*bob) # Name: Bob Age: 41 Company: Apple
Перебор кортежей
Для перебора кортежа можно использовать стандартные циклы for и while . С помощью цикла for:
tom = ("Tom", 22, "Google") for item in tom: print(item)
С помощью цикла while:
tom = ("Tom", 22, "Google") i = 0 while i < len(tom): print(tom[i]) i += 1
Проверка наличия значения
Как для списка с помощью выражения элемент in кортеж можно проверить наличие элемента в кортеже:
user = ("Tom", 22, "Google") name = "Tom" if name in user: print("Пользователя зовут Tom") else: print("Пользователь имеет другое имя")
Кортежи в Python
- Понятие кортежа в Python
- Создание кортежей в Python
- Доступ по индексу и срезы кортежей
- Операторы кортежей в Python
- Функции и методы кортежей в Python
- Зачем нужны кортежи, если есть списки?
- Краткие итоги параграфа
- Вопросы и задания для самоконтроля
Понятие кортежа в Python
Еще одной упорядоченной коллекцией объектов в Python являются кортежи, которые практически во всем похожи на списки. Однако в отличие от списков кортежи не могут изменяться непосредственно, поэтому многие операции применимые к спискам, становятся недоступными для кортежей. Кроме того, литералы кортежей записываются не в квадратных, а в круглых скобках. Итак, что же такое кортеж?
(от англ. tuple) – это неизменяемая упорядоченная коллекция объектов произвольного типа. Сами объекты называются , а доступ к ним может быть получен при помощи целочисленного индекса или среза.
Поскольку кортежи очень похожи на списки, дальнейшее изложение материала будет практически полностью дублировать содержание параграфа о списках. Однако пренебрегать чтением и решением задач не стоит, т.к. это хорошая возможность еще раз повторить и закрепить основные понятия, связанные с упорядоченными последовательностями.
Создание кортежей в Python
Проще всего литерал кортежа в Python создается при помощи круглых скобок, внутри которых элементы кортежа перечисляются через запятую (см. пример №1 ). В случае необходимости последний элемент кортежа можно также завершать запятой. Это никак не повлияет на количество элементов кортежа, а значит и его длину. Однако, если кортеж состоит из одного элемента, то запятую после него нужно указывать обязательно, иначе интерпретатор не сможет отличить кортеж от простого значения или выражения.
Код Результат pythonCodes
# Получаем пустой кортеж. tpl_1 = () # Выведет (). print(tpl_1, end='\n\n') # Получаем кортеж с одним элементом. # (3) нельзя, т.к. это просто число 3. tpl_2 = (3,) # Выведет (3,). print(tpl_2, end='\n\n') # Элементы перечисляем через запятую. tpl_3 = (15, "Иван", None, 34.5, True) # Выведет (15, 'Иван', None, 34.5, True). print(tpl_3, end='\n\n') # Последнюю запятую можно не опускать. tpl_4 = (1, 2, 3,) # Выведет (1, 2, 3). print(tpl_4, end='\n\n') # Эл-ми могут быть любые объекты, любой вложенности. tpl_5 = ( , 0.3, ) # Выведет (, 0.3). print(tpl_5)
() (3,) (15, 'Иван', None, 34.5, True) (1, 2, 3) (, 0.3)
Пример №1. Создание кортежей в Python (часть 1).
Как видим, внутри кортежей действительно разрешается использовать объекты любого типа данных, создавая при этом любые их комбинации и уровни вложенности. А благодаря наличию в синтаксисе круглых скобок, сложные и объемные литералы кортежей можно без проблем записывать на нескольких строках, придавая исходному коду удобочитаемый вид.
Создать кортеж можно также при помощи встроенного конструктора типа tuple() . Если использовать его без аргумента, то он вернет нам пустой кортеж. Если же передать ему итерируемый объект, например, строку или список, то конструктор вернет кортеж, элементами которого будут соответствующие элементы переданного объекта (см. пример №2 ).
Код Результат pythonCodes
# Получаем пустой кортеж. tpl_1 = tuple() # Выведет (). print(tpl_1, end='\n\n') # Получаем кортеж из строки. tpl_2 = tuple('123') # Выведет ('1', '2', '3'). print(tpl_2, end='\n\n') # Преобразуем список в кортеж. tpl_3 = tuple([15, "Иван", None, 34.5, True]) # Выведет (15, 'Иван', None, 34.5, True). print(tpl_3)
() ('1', '2', '3') (15, 'Иван', None, 34.5, True)
Пример №2. Создание кортежей в Python (часть 2).
Что касается генераторов, то создать кортеж с их помощью не получится, т.к. как генераторы заключенные в круглые скобки сами являются «выражениями генераторами».
Доступ по индексу и срезы кортежей
Операции доступа по индексу и получения срезов для кортежей имеют практически тот же самый синтаксис и смысл, что и для списков (см. пример №3 ).
Код Результат pythonCodes
# Формируем кортеж из целых чисел. # Можно и без скобок, но лучше явно определять кортеж. tpl_1 = 1, 2, 3, 4, 5 # Получим 1, т.е. 1-й эл-т кортежа (нумерация начинается с нуля). print('tpl_1[0] ->', tpl_1[0], end='\n\n') # Выводим последний эл-т кортежа (кол-во эл-тов кортежа минус один). # Получим 5. print('tpl_1[len(tpl_1)-1] ->', tpl_1[len(tpl_1)-1], end='\n\n') # Можно использовать отрицательные индексы, тогда # нумерация будет идти с конца и начинаться с -1. # Опять же получим 5. print('tpl_1[-1] ->', tpl_1[-1])
tpl_1[0] -> 1 tpl_1[len(tpl_1)-1] -> 5 tpl_1[-1] -> 5
Пример №3. Доступ к элементам кортежа по индексу (часть 1).
В принципе во многих случаях можно определять кортеж и без использования круглых скобок, т.к. для его определения важно именно наличие запятых между объектами, которые станут элементами кортежа. Однако все зависит от конкретной ситуации. Например, запись вида my_func(x, y) означает, что данной функции должно быть передано два аргумента, а запись my_func((x, y)) означает, что функции должен быть передан кортеж из двух элементов. Так что лучше всегда явно определять кортеж, используя для этого круглые скобки.
Поскольку в результате обращения к элементу кортежа по его индексу возвращается некоторый объект, расположенный по указанному смещению, то для получения доступа к элементам на более глубоком уровне вложенности может потребоваться целая цепочка из нескольких индексов (см. пример №4 ).
Код Результат pythonCodes
# Простой пример вложенных в кортеж списков. tpl_1 = (3.14, ['abc', [4, 5]], 'кот') # Выводим число 3.14 (1-й элемент кортежа). print('tpl_1[0] ->', tpl_1[0], end='\n\n') # Выводим 2-й символ строки 'кот'. print('tpl_1[2][1] ->', tpl_1[2][1], end='\n\n') # Выводим 3-й символ строки 'abc'. print('tpl_1[1][0][2] ->', tpl_1[1][0][2], end='\n\n') # Выводим число 5 вложенного списка [4, 5]. print('tpl_1[1][1][1] ->', tpl_1[1][1][1])
tpl_1[0] -> 3.14 tpl_1[2][1] -> о tpl_1[1][0][2] -> c tpl_1[1][1][1] -> 5
Пример №4. Доступ к элементам кортежа по индексу (часть 2).
Следует отметить, что цепочка доступа к конкретному элементу может иметь и более сложную конструкцию, включающую не только квадратные скобки с индексами для доступа к элементам строк, кортежей или списков, но и квадратные скобки с ключами для доступа к элементам словарей, и точки для доступа к атрибутам объектов. Например, для кортежа tpl = (, 0.3) цепочка получения доступа ко второму элементу вложенного списка [4, 5] будет иметь вид tpl[0]['two'][1][1] .
Что касается получения срезов для кортежей, то для них справедлив тот же порядок, что и для других упорядоченных коллекций, т.е. строк и списков (см. пример №5 ).
Код Результат pythonCodes
# Формируем кортеж из целых чисел. tpl_1 = (1, 2, 3, 4, 5, 6, 7) # Получаем кортеж из первых двух эл-тов. print('tpl_1[0:2] ->', tpl_1[0:2], end='\n\n') # Можно и так, все равно получим (1, 2). print('tpl_1[:2] ->', tpl_1[:2], end='\n\n') # Получаем кортеж из посл-х двух эл-тов ((6, 7)). print('tpl_1[-2:] ->', tpl_1[-2:], end='\n\n') # Получаем кортеж (3, 4, 5) из эл-тов с 3-го по 5-й. print('tpl_1[2:5] ->', tpl_1[2:5], end='\n\n') # Получим (2, 3, 4, 5) (использ. отриц. индексы). print('tpl_1[-6:-2] ->', tpl_1[-6:-2], end='\n\n') # Убедимся, что кортеж не изменился. print('tpl_1 ->', tpl_1, end='\n\n') # Напоследок выведем копию кортежа. print('tpl_1[:] ->', tpl_1[:])
tpl_1[0:2] -> (1, 2) tpl_1[:2] -> (1, 2) tpl_1[-2:] -> (6, 7) tpl_1[2:5] -> (3, 4, 5) tpl_1[-6:-2] -> (2, 3, 4, 5) tpl_1 -> (1, 2, 3, 4, 5, 6, 7) tpl_1[:] -> (1, 2, 3, 4, 5, 6, 7)
Пример №5. Операция взятия среза у кортежей.
Опять же, при извлечении срезов следует помнить, что нумерация элементов в кортежах начинается с нуля, а элемент с индексом второго предела, указанного в квадратных скобках, не будет присутствовать в срезе. Например, в срезе кортежа tpl_1[0:5] будут присутствовать первые пять элементов с индексами от 0 до 4 , но не включая элемент с индексом 5 .
Как и в случае со строками и списками, один или оба предела среза можно опускать. Если не указывать первый предел, интерпретатор будет начинать срез с первого элемента кортежа (с индексом 0 ), а при отсутствии второго предела срез будет идти до конца кортежа. Если опустить оба предела, мы получим копию кортежа. При необходимости разрешается указывать и третий предел, который будет задавать шаг среза (см. пример №6 ).
Код Результат pythonCodes
# Формируем кортеж из целых чисел. tpl_1 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) # Выводим его для наглядности. print('tpl_1 ->', tpl_1, end='\n\n') # Выводим каждый 2-й элемент среза (слева направо). # (1, 3, 5, 7). print('tpl_1[0:7:2] ->', tpl_1[0:7:2], end='\n\n') # Можно и так, получим опять (1, 3, 5, 7). print('tpl_1[:7:2] ->', tpl_1[:7:2], end='\n\n') # Выводим каждый третий элемент всего кортежа. # (1, 4, 7, 10). print('tpl_1[::3] ->', tpl_1[::3], end='\n\n') # Выводим каждый 2-й эл-т, считая с конца среза (-1, -2. ). # Сам срез берется справа налево, если шаг отрицательный. # (9, 7, 5). print('tpl_1[8:2:-2] ->', tpl_1[8:2:-2], end='\n\n') # Выводим каждый 3-й эл-т среза, считая справа налево. # (8, 5). print('tpl_1[-3:1:-3] ->', tpl_1[-3:1:-3], end='\n\n') # Выводим каждый 2-й эл-т, считая с конца кортежа. # (10, 8, 6, 4, 2). print('tpl_1[::-2] ->', tpl_1[::-2])
tpl_1 -> (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) tpl_1[0:7:2] -> (1, 3, 5, 7) tpl_1[:7:2] -> (1, 3, 5, 7) tpl_1[::3] -> (1, 4, 7, 10) tpl_1[8:2:-2] -> (9, 7, 5) tpl_1[-3:1:-3] -> (8, 5) tpl_1[::-2] -> (10, 8, 6, 4, 2)
Пример №6. Порядок использования шага среза у кортежей.
Как видим, шаг среза также может иметь отрицательное значение (аналогично спискам и строкам). В этом случае отсчет элементов кортежа и шагов ведется в противоположном направлении, а границы среза указываются справа налево, т.е. индекс элемента, стоящего правее в кортеже должен указываться первым. Например, в срезе примера tpl_1[-3:1:-3] отсчет ведется справа налево, начиная с 3 -го элемента, отсчитываемого с конца кортежа, до элемента с индексом 1 , который находится левее и в срез не включается.
Неизменяемость кортежей означает, что для них запрещены операции добавления новых элементов, а также удаления или замены уже существующих. При этом мы спокойно можем изменять конкретные элементы кортежа, если они это допускают (см. пример №7 ).
Код Результат pythonCodes
# Формируем кортеж из 3-х элементов. tpl_1 = ('и', ['b', [4, 5]], 0.3) # Изменяем 1-й эл-т вложенного списка [4, 5]. tpl_1[1][1][0] = 's' # Выведет ('и', ['b', ['s', 5]], 4). print('tpl_1[1][1][0] = \'s\' ->', tpl_1, end='\n\n') # А вот так уже не получится (кортеж неизменяем). tpl_1[0] = 7 # Выведет исключение. print('tpl_1[0] = 7 ->', tpl_1)
tpl_1[1][1][0] = 's' -> ('и', ['b', ['s', 5]], 0.3) 'tuple' object does not support item assignment
Пример №7. Изменение элементов кортежей.
Операторы кортежей в Python
Поскольку кортежи относятся к упорядоченным последовательностям, операторы + , += , * и *= имеют для них практически тот же смысл, что и для списков и строк (см. пример №8 ).
Код Результат pythonCodes
# Формируем кортежи. tpl_1 = (1, 2, 3) tpl_2 = (4, 5, 6) # Осуществляем конкатенацию кортежей (т.е. объединение). # Выведет (1, 2, 3, 4, 5, 6). print('tpl_1 + tpl_2 ->', tpl_1 + tpl_2, end='\n\n') # Объединяем с самим собой 3 раза (tpl_1 + tpl_1 + tpl_1). # Выведет (1, 2, 3, 1, 2, 3, 1, 2, 3). print('tpl_1*3 ->', tpl_1*3, end='\n\n') # Тоже, что и tpl_1 = tpl_1 + tpl_2. tpl_1 += tpl_2 # Теперь tpl_1 == (1, 2, 3, 4, 5, 6). print('tpl_1 += tpl_2 ->', tpl_1)
tpl_1 + tpl_2 -> (1, 2, 3, 4, 5, 6) tpl_1*3 -> (1, 2, 3, 1, 2, 3, 1, 2, 3) tpl_1 += tpl_2 -> (1, 2, 3, 4, 5, 6)
Пример №8. Использование операторов + и * применительно к кортежам.
Незабываем, что по обе стороны от оператора сложения должны находиться кортежи (в общем случае это должны быть последовательности одного и того же типа), т.к. интерпретатор не занимается автоматическим приведением типов и просто выдаст ошибку.
Далее. В отношении элементов кортежа мы можем использовать оператор проверки на вхождение in , который совершает поиск требуемого объекта (левый операнд) среди элементов целевого кортежа (правый операнд). Опять же, в случае успеха операция возвращает True , иначе – False (см. пример №9 ).
Код Результат pythonCodes
# Формируем кортеж. tpl_1 = (1, 2, 3, [4, 5]) # Проверяем наличие числа 8 в кортеже. answer = 8 in tpl_1 # Если операция вернула True, if answer: # выводим подтверждение на экран. print('Число 8 присутствует в кортеже tpl_1.', end='\n\n') # Иначе else: # выводим на экран отрицание. print('Числа 8 нет в кортеже tpl_1.', end='\n\n') # Проверим вхождение, используя not in. if 5 not in tpl_1[3]: # Выводим подтверждение на экран. print('Число 5 отсутствует в tpl_1[3].') # Иначе else: # Выводим на экран сообщение. print('Число 5 присутствует в tpl_1[3].')
Числа 8 нет в кортеже tpl_1. Число 5 присутствует в tpl_1[3].
Пример №9. Использование оператора in применительно к кортежам.
Напомним, что оператор in может использоваться не только самостоятельно, но и совместно с оператором отрицания not , который инверсирует возвращаемое логическое значение оператора in . Соответственно, например, операция 'крот' not in ('кот', 'кит') вернет True вместо False .
Если возникает необходимость в обходе элементов кортежа, то, по аналогии со строками и списками, можно смело использовать оператор цикла for (см. пример №10 ).
Код Результат pythonCodes
# Формируем кортеж. tpl_1 = (1, 2, 3, 4, 5) # Проверим все ли числа в кортеже целые. for elem in tpl_1: # Если эл-т не является целым числом, if type(elem) is not int: # выводим сообщение на экран print('Не все эл-ты кортежа целые числа.') # и прерываем цикл. break # Eсли цикл завершился успешно, else: # выводим положительный результат. print('Все эл-ты в кортеже - целые числа.')
Все эл-ты в кортеже - целые числа.
Пример №10. Использование цикла for для обхода элементов кортежа.
Поскольку кортежи относятся к неизменяемым последовательностям, оператор удаления del к элементам кортежа неприменим, хотя сам кортеж данный оператор спокойно удаляет.
Функции и методы кортежей в Python
Что касается методов кортежей, то для них применимы общие методы упорядоченных последовательностей, которые не приводят к их изменению. Я насчитал всего два таких метода.
- tpl.count(x) – возвращает количество элементов с указанным значением x в целевом кортеже tpl (см. пример №11 ). Отметим, что в отличие от аналогичного метода для строк, здесь указывать интервал для поиска нельзя, т.к. метод принимает только один аргумент.
- tpl.index(x[, start[, end]]) – возвращает индекс i первого вхождения элемента tpl[i] со значением x в целевой кортеж tpl или в срез кортежа tpl[start:end] , если он задан. В случае неудачного поиска метод вызывает исключение ValueError . Обратите внимание, что при использовании среза отсчет индекса элемента все равно стартует с начала всего кортежа.
Код Результат pythonCodes
# Создаем кортеж для манипуляций. tpl = ('a', 'b', 'c', 'a', 'b', 'c') # Ищем кол-во эл-тов со значением 'b' n_1 = tpl.count('b') # Получим 2. print('tpl.count("b") ->', n_1) # Ищем кол-во эл-тов со значением 23 n_2 = tpl.count(23) # Получим 0, т.к. эл-тов с таким значением нет в кортеже. print('tpl.count(23) ->', n_2, end='\n\n') # Ищем индекс 1-го встретившегося эл-та со значением 'c'. index_1 = tpl.index('c') # Выведет 2. print('tpl.index("c") ->', index_1) # Тоже самое, но ищем с 4-го элемента кортежа. index_2 = tpl.index('c', 3) # Получим индекс 5, т.к. ищем не сначала кортежа. print('tpl.index("c", 3) ->', index_2)
tpl.count("b") -> 2 tpl.count(23) -> 0 tpl.index("c") -> 2 tpl.index("c", 3) -> 5
Пример №11. Методы кортежей.
Применимы к кортежам и некоторые встроенные функции, которые получают доступ к элементам кортежа, но не изменяют его непосредственно: len() (возвращает количество элементов в кортеже), min() (возвращает элемент с минимальным значением, при этом элементы должны быть одного типа с возможностью сравнения), max() (возвращает элемент с максимальным значением, при этом элементы должны быть одного типа с возможностью сравнения), sum() (возвращает сумму элементов кортежа, при этом элементы должны быть числами) и т. д.
Зачем нужны кортежи, если есть списки?
«Ну, и зачем нам эти кортежи, если есть списки?» – часто спрашивают начинающие программисты. Действительно, кортежи копируют списки и при этом сильно ограничены в возможностях, да еще и неизменяемые. Однако ключевая мысль здесь – «неизменяемые». Благодаря этому мы можем быть уверены, что кортеж не будет изменен через другую ссылку в другом месте программы. Кроме того, встречаются ситуации, когда использование списков недопустимо, например, в качестве ключей словаря кортежи можно использовать, а списки нет. Именно поэтому, когда в программе нужно использовать упорядоченные коллекции объектов с возможностью их изменения в будущем, нужно выбирать списки; если же нужны фиксированные коллекции объектов, следует выбирать кортежи.
Хотя сами кортежи и неизменяемы, они могут содержать элементы изменяемых типов (например, списки или словари), а те могут быть изменены программой. Такие кортежи использовать в качестве ключей словаря не получится.
Второй важной особенностью кортежей является то, что за счет неизменяемости, а значит и более простой внутренней структуры, кортежи в общем случае занимают в памяти меньше места, чем списки (см. пример №12 ). Как следствие, операции с кортежами являются более производительными, хотя и не такими гибкими.
Код Результат pythonCodes
# Импортируем модуль sys. import sys # Создаем кортеж и список. tpl = (1, 2, 3, 4, 5) li = [1, 2, 3, 4, 5] # Получаем размеры. print('Размер tpl:', sys.getsizeof(tpl)) print('Размер li:', sys.getsizeof(li))
Размер tpl: 80 Размер li: 120
Пример №12. Отличие кортежей от списков.
Краткие итоги параграфа
- В Python кортежи представляют собой упорядоченные, но неизменяемые, коллекции объектов произвольного типа с доступом по индексу.
- Чтобы создать кортеж достаточно перечислить требуемые объекты (элементы кортежа) через запятую внутри круглых скобок (например, tpl = (3.7, 'оса', [1, 2]) ). Здесь стоит не забывать, что если таким образом создается кортеж с одним элементом, после него следует ставить запятую (например, tpl = (7,) ).
- Также кортежи могут быть созданы при помощи функции tuple(iterable) (например, инструкция tuple('abc') вернет кортеж ('a', 'b', 'c') ).
- Использовать для создания кортежей генераторы нельзя, т.к. генераторы заключенные в круглые скобки сами являются «выражениями генераторами».
- После создания кортежа доступ к любому элементу кортежа можно получить по его индексу, т.е. порядковому номеру элемента в кортеже. При этом следует помнить, что индексация элементов в кортежах начинается с нуля (например, инструкция print(tpl[1]) выведет второй элемент последнего кортежа, т.е. строку 'b' ).
- Что касается срезов, то для кортежей они имеют практически тот же смысл, что и для строк и списков. Главное не забывать, что кортежи неизменяемы, и не пытаться использовать срезы для замены, удаления или добавления элементов в кортеж.
- Арифметические операторы + и * , а также их комбинированные собратья += и *= , работают с кортежами по хорошо известной нам схеме, т.е. практически так же, как со строками и списками.
- Оператор удаления del в отношении элементов кортежа неприменим. А вот оператор in и цикл for как раз наоборот: первый как всегда совершает поиск требуемого объекта среди элементов целевого кортежа, а второй позволяет поочередно обойти все его элементы.
- Из методов для кортежей доступны только общие методы упорядоченных последовательностей. Это tpl.count(x) , который подсчитывает количество элементов с указанным значением x , и tpl.index(x[, start[, end]]) , который возвращает индекс i первого вхождения в кортеж элемента tpl[i] со значением x ). Найти эти методы можно в подразделе «Sequence Types – list, tuple, range» раздела «Built-in types» стандартной библиотеки.
- Благодаря своей неизменяемости кортежи занимают в памяти меньше места, чем списки, а операции с ними являются более производительными. При этом следует помнить, что хотя сами кортежи и неизменяемы, их элементы изменяемых типов (например, списки или словари) могут быть изменены программой (такие кортежи использовать в качестве ключей словаря не получится).
Помогите проекту, подпишитесь!
Подписка на учебные материалы сайта оформляется сроком на один год и стоит около 15 у.е. 5 у.е. После подписки вам станут доступны следующие возможности.
- Доступ ко всем ответам тестов и решениям задач.
- Возможность загрузки учебных кодов и программ на свой компьютер. Доступ ко всем видеоурокам.
- Практически полное отключение рекламы.
- Возможность внести свой скромный вклад в развитие проекта и мира во всем мире, а также выразить свою благодарить автору за его труд. Нам очень нужна ваша поддержка!
На страницу подписки
Вопросы и задания для самоконтроля
1. Какие из утверждений относятся к кортежам: коллекция объектов, упорядоченная последовательность, неизменяемая и неупорядоченная последовательность, изменяемая неупорядоченная коллекция объектов, неизменяемая упорядоченная последовательность элементов? Показать решение.
Ответ. Кортежи – это неизменяемые упорядоченные коллекции объектов (последовательности элементов) произвольного типа. Значит по отношению к ним верны утверждения: коллекция объектов, упорядоченная последовательность, неизменяемая упорядоченная последовательность элементов.
2. Разрешается ли использовать в качестве элементов кортежа списки? Показать решение.
Ответ. Кортежи – это неизменяемые упорядоченные коллекции объектов произвольного типа. Значит мы можем использовать в качестве их элементов и списки, и словари и любые другие изменяемые объекты.
3. Для чего нужны кортежи, если есть списки? Показать решение.
Ответ. Кортежи неизменяемы, поэтому они могут использоваться в качестве ключей словаря (пусть и с ограничениями на неизменяемость вложенных элементов), а также хорошо подходят для случаев, когда нужно быть уверенным в целостности данных. Кроме того, кортежи занимают меньше памяти, чем списки, а значит с кортежами производительность операций будет выше.
4. Какие из представленых литералов относятся к типу tuple : ('tuple', 'list') , '(3, 4)' , (5,) , 'Питон, Python' ? Проверьте типы программно. Показать решение.
Ответ. Тип tuple : ('tuple', 'list') , (5,) .
Решение Результат pythonCodes
# Выводим типы представленных литералов. print("Тип ('tuple', 'list'):", type(('tuple', 'list'))) print("Тип '(3, 4)':", type('(3, 4)')) print("Тип (5,):", type((5,))) print("Тип 'Питон, Python':", type('Питон, Python'))
Тип ('tuple', 'list'): Тип '(3, 4)': Тип (5,): Тип 'Питон, Python':
5. Дан кортеж (([1, 2], ['012', 'abc']), [4, 3]) . Как получить доступ к символу 'c' строки 'abc' ? Показать решение.
Ответ. Доступ к элементам вложенных последовательностей вроде списков, строк или кортежей можно получить через последовательную цепочку обращений по индексу.
Решение Результат pythonCodes
# Сохраняем кортеж в переменной. tpl = (([1, 2], ['012', 'abc']), [4, 3]) # Используем цепочку доступа по индексу. print(tpl[0][1][1][2])
6. Какие значения будут присвоены переменным в инструкциях tpl_1 = (1, 2, 3, 4, 5, 6, 7)[1:4] , tpl_2 = (1, 2, 3, 4, 5, 6, 7)[-4:-3] и tpl_3 = (1, 2, 3, 4, 5, 6, 7)[::2] ? Проверьте свой ответ программно. Показать решение.
Условие Решение pythonCodes
# Получаем срезы. tpl_1 = (1, 2, 3, 4, 5, 6, 7)[1:4] tpl_2 = (1, 2, 3, 4, 5, 6, 7)[-4:-3] tpl_3 = (1, 2, 3, 4, 5, 6, 7)[::2] # Выведет (2, 3, 4]. print('tpl_1:', tpl_1) # Выведет (4,) (с запятой!). print('tpl_2:', tpl_2) # Выведет (1, 3, 5, 7). print('tpl_3:', tpl_3)
tpl_1: (2, 3, 4) tpl_2: (4,) tpl_3: (1, 3, 5, 7)
7. Имеется кортеж (1, 2, 3) . В нем необходимо заменить первый элемент и получить кортеж (5, 2, 3) . Как это сделать, ведь кортежи неизменяемы? Показать решение.
Ответ. Да, кортежи относятся к неизменяемым типам данных. Поэтому изменить их непосредственно не получится, но никто не запрещает нам создать новый кортеж с желаемым значением.
Решение Результат pythonCodes
# Сохраним кортеж в переменной. tpl = (1, 2, 3) # Создаем новый кортеж, используя операции # конкатенации и извлечения среза. tpl_1 = (5,) + tpl[1:] # Выводим новый кортеж на экран. print(tpl_1) # Используем дорогостоящую операцию # преобразования в список и обратно. li = list(tpl) li[0] = 5 tpl_2 = tuple(li) # Выводим новый кортеж на экран. print(tpl_2)
(5, 2, 3) (5, 2, 3)
8. Что произойдет, если в кортеже (1, [2, 3]) попытаться изменить в списке одно из значений? Объясните свой ответ. Показать решение.
Ответ. Мы не можем изменять сами кортежи, т.е. удалять, добавлять или перемещать его элементы, которые представляют собой объекты произвольного типа. Однако изменять значения элементов кортежа, которые являются объектами изменяемых типов мы можем. Поэтому мы можем свободно изменить любое из значений списка данного кортежа.
Решение Результат pythonCodes
# Целевой кортеж. tpl = (1, [2, 3]) # Выведет (1, [2, 3]). print('tpl:', tpl) # Вносим изменения в список. tpl[1][0] = 5 # Выведет (1, [5, 3]). print('tpl:', tpl)
tpl: (1, [2, 3]) tpl: (1, [5, 3])
9. Что можно сказать про методы с именами count , split , index и clear в контексте кортежей? Показать решение.
Ответ. Кортежи, как и строки, относятся к неизменяемым типам данных. Поэтому у них отсутствуют методы split и clear , которые связаны с изменением кортежей.
10. Дополнительные тесты по теме расположены в разделе «Кортежи» нашего сборника тестов.
11. Дополнительные упражнения и задачи по теме расположены в разделе «Кортежи» нашего сборника задач и упражнений.
Быстрый переход к другим страницам
- Списки в Python
- Кортежи в Python
- Словари в Python
- Вернуться к оглавлению учебника
okpython.net Copyright © 2022-2023.