C кортеж – отличие от списков, основной синтаксис, примеры создания

создание и приведение к списку

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

Что такое кортеж

Кортеж – это неизменная структура заданных заранее значений. Он очень похож на список, но последний подвержен изменениям. Так, если нужно исправить какой-то элемент списка, можно сделать это, напрямую указав:

b = [4, 6, 8]
print(b)
[4, 6, 8]
b[1] = 13
print(b)
[4, 13, 8]

Если же записать подобный код, но попытаться применить его к кортежу, ничего не выйдет, а на экране появится надпись об ошибке. Считается, что это важно, поскольку таким образом данные невозможно будет изменить как случайно, так и намеренно. Также в python добавление элемента в кортеж невозможно. Правда можно привести его в список, добавить элемент. После этого полученный список преобразовать обратно.

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

a = (2, 4, 6, 8, 10, 12)
b = [2, 4, 6, 8, 10, 12]
a.__sizeof__()
36
b.__sizeof__()
44

Из этого кода видно, что кортеж (в круглых скобках) занимает 36 байтов, а список (в квадратных скобках) – 44 байта.

Создание

Кортеж определяется точно так же, как и список, однако перечисление происходит в круглых, а не квадратных скобках. Элементы будут стоять в определенном порядке, а их нумерация всегда начинается с нуля. А точнее для непустого кортежа первым элементом будет являться ноль. Отрицательный индекс позволит отсчитывать все с конца (с правой стороны).

Приведем пример создания в Python обычного кортежа:

a = (1,2,3)

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

a = tuple([1,2,3])

Рассмотрим кортеж с отрицательным индексом:

n = ("a", "b", "с", "d", "e")
print(n[-1])

'e'

То есть на экране отобразился первый не с начала, а с конца элемент.

Чтобы создать кортеж с одним элементом, нужно сделать такую запись:

a =(3,)
print(a[0])

3

Нужно обратить особое внимание на то, что даже если элемент один, после него все равно должна стоять запятая.

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

a = tuple(i for i in range(0, 10))
print(a)

(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Выше представлен генератор кортежа. То есть мы создали генератор. После этого преобразовали его к кортежу с помощью ключевого слова tuple.

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

Подробнее о срезах описано ниже в пункте “Обращение к элементу”.

Использование генераторов кортежей аналогично генераторам списка.

Обращение к элементу

У каждого элемента есть свой индекс. То есть, в Python для обращения к элементу кортежа, нужно просто указать его индекс. Напомним, что счет начинается с нуля. Посмотрим на код:

b = (4, 6, 8)
print(b[0])
print(b[1])

4
6

Из кортежа можно извлечь как элемент, так и срез. В этом случае мы получим кортеж, состоящий из элементов, расположенных в промежутке среза. Следует уточнить, что при указании среза используются не номера элементов, а номера промежутков между ними. Перед первым элементом находится промежуток с индексом 0. Рассмотрим пример:

b = (5, 3.6, "квадрат", 15, 'В')
print(b[1])
print(b[2:4])

3.6
('квадрат', 15)

Методы

Кортежи в python имеют только два метода: index() и count(). Первый применяется, чтобы узнать, какой индекс у определенного элемента. Например:

a = (32, 33, 34, 33, 34, 33)
print(a.index(33))

1

Элементов «33» в кортеже несколько, но на экран будет выведен индекс первого из них.

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

a = (32, 33, 34, 33, 34, 33)
print(a.count(33))

3

На экране перед пользователем появится именно число 3, потому что в кортеже искомое число 33 повторяется 3 раза.

Помните, что в кортежах нет методов добавления и удаления элементов.

Именованные кортежи

Данный класс не получил широкого применения среди программистов, хотя он и является достаточно важным и полезным. Именованные кортежи в python (или namedtuple) в каком-то смысле являются расширениями для обычных. Так, огромной проблемой считается то, что получать данные из кортежа можно только при помощи числовых индексов. А что делать, если хочется для наглядности кода обращаться к элементам, используя строковое наименование. Такое обращение значительно улучшит читаемость кода. Для этого на помощь приходит namedtuple.

Для того, чтобы использовать namedtuple, необходимо подключить библиотеку collections. Это делается с помощью import collecions *. В этом случае обращаться к namedtuple будет необходимо следующим образом: collections.namedtuple( [параметры] ). Другой вариант подключения библиотеки приведен в примере ниже.

Каждый элемент, сохраненный в именованном кортеже, доступен через определенный идентификатор. Посмотрим на примере кода:

from collections import namedtuple
Flower = namedtuple('Flower' , 'color cost comment')
rose = Flower('red', 5, 'beautiful')
print(rose.cost)

5

Наименования полей были перечислены через пробел. Вместо этой строки можно было передать список со строками. В конструкторе namedtuple разобьет полученную строку с помощью split. В качестве примера было приведено обращение к элементу cost. К остальным обращение аналогично: rose.color, rose.comment.

Таким образом, именованный кортеж делает вид программного кода более читаемым. Так, в вышеуказанном коде можно увидеть наименования color, cost и comment. И при всем при этом, сохраняется возможность обращения к элементам по индексу, например дописав к предыдущему коду:

print(rose[0])

red

Список кортежей

Иногда бывают задачи, в которых нужно хранить таблицы с данными, которые называются матрицами (или двумерными массивами). Для работы с массивами используется библиотека array. К сожалению, не получится с ее помощью сделать массив кортежей. Потому что элементом массива не может быть кортеж.

Из этой ситуации есть выход – создание в Python списка кортежей. Вариант объявления такого списка представлен ниже:

a = [(1,2,3),(4,5,6)]

Cортировка

Иногда нужно отсортировать имеющиеся элементы списка. Благодаря встроенной функции sorted, все это делается достаточно легко:

a = ('One', 'Two', 'Three')
a = tuple(sorted(a))
print(a)

('One', 'Three', 'Two')

Видно, что произошла сортировка кортежа Python по алфавиту. Стандартную сортировку можно провести и по числовым элементом. Посмотрим на пример:

a = (3, 1, 5 ,2, 6, 7)
a = tuple(sorted(a))
print(a)

(1, 2, 3, 5, 6, 7)

Заметим, что произошла сортировка по возрастанию.

Обратите внимание, что функция sorted возвращает список, но с помощью tuple мы приводим результат сортировки к кортежу.

В список

Кортеж можно переделать в список:

a = (1,2,3)
a = list(a)
print(a)

[1, 2, 3]

Таким образом, кортеж был преобразован в список Python, который можно изменить. Теперь рассмотрим обратное действие — преобразование списка в кортеж:

a = [1, 2.6, "квадрат"]
a = tuple(a)
print(a)

(1, 2.6, "квадрат")

В словарь

Словарь – это еще одна структура используемая в Python. Он, как и список, является изменяемым, но при этом неупорядоченным. Это значит, что обратиться к определенному элементу посредством указания индекса – не получится. Чтобы лучше понять, можно провести аналогию с обычным англо-русским словарем. В нем для каждого слова есть перевод: house –дом, flat – квартира, window – окно. Если перенести такую структуру в программный код, то получится такая запись, оформляемая фигурными скобками:

{'house': 'дом', 'flat': 'квартира', 'window': 'окно'}

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

Для того, чтобы в Python преобразовать кортеж в словарь, необходимо использовать приведение типов с помощью dict.

a = (('a', 2),('b', 4))
a = dict(a)
print(a)

{'a': 2, 'b': 4}

Как видно, для создания словаря понадобился кортеж кортежей. Причем вложенные кортежи состоят из двух элементов каждый. Иначе не получается провести преобразование к словарю.

В строку

Чтобы вывести в python кортеж в одну строку, используется функция join. Посмотрим на примере:

a = ('one','two','three')
b = ''.join(a)
c = ','.join(a)
print(b)
print(c)

onetwothree
one,two,three

После выполнения кода на дисплее появится запись всех элементов в одну строку с указанным разделителем. В первом случае – без пробелов, а во втором случае – через запятую.

Чем же кортежи удобнее? Работа с ними проходит быстрее, чем, например, со списками. Если программисту нужно определить постоянный набор значений, чтобы затем их перебирать, то лучше будет сделать это с его помощью. Плюс – это экономия оперативной памяти, так как они занимают меньше места, чем списки.

all-python.ru

Python. Урок 8. Кортежи (tuple)

Данный урок посвящен кортежам (tuple) в Python. Основное внимание уделено вопросу использования кортежей, почему иногда лучше применять их, а не списки, рассмотрены способы создания и основные приемы работы с кортежами. Также затронем тему преобразования кортежа в список и обратно.

Что такое кортеж (tuple) в Python?

Кортеж (tuple) – это неизменяемая структура данных, которая по своему подобию очень похожа на список. Как вы наверное знаете, а если нет, то, пожалуйста, ознакомьтесь с седьмым уроком, список – это изменяемый тип данных. Т.е. если у нас есть список a = [1, 2, 3] и мы хотим заменить второй элемент с 2 на 15, то мы может это сделать, напрямую обратившись к элементу списка.

>>> a = [1, 2, 3]
>>> print(a)
[1, 2, 3]
>>> a[1] = 15
>>> print(a)
[1, 15, 3]

С кортежем мы не можем производить такие операции, т.к. элементы его изменять нельзя.

>>> b = (1, 2, 3)
>>> print(b)
(1, 2, 3)
>>> b[1] = 15
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    b[1] = 15
TypeError: 'tuple' object does not support item assignment

Зачем нужны кортежи в Python?

Существует несколько причин, по которым стоит использовать кортежи вместо списков. Одна из них – это обезопасить данные от случайного изменения. Если мы получили откуда-то массив данных, и у нас есть желание поработать с ним, но при этом непосредственно менять данные мы не собираемся, тогда, это как раз тот случай, когда кортежи придутся как нельзя кстати. Используя их в данной задаче, мы дополнительно получаем сразу несколько бонусов – во-первых, это экономия места. Дело в том, что кортежи в памяти занимают меньший объем по сравнению со списками.

>>> lst = [10, 20, 30]
>>> tpl = (10, 20, 30)
>>> print(lst.__sizeof__())
32
>>> print(tpl.__sizeof__())
24

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

Создание, удаление кортежей и работа с его элементами

Создание кортежей

Для создания пустого кортежа можно воспользоваться одной из следующих команд.

>>> a = ()
>>> print(type(a))
<class 'tuple'>
>>> b = tuple()
>>> print(type(b))
<class 'tuple'>

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

>>> a = (1, 2, 3, 4, 5)
>>> print(type(a))
<class 'tuple'>
>>> print(a)
(1, 2, 3, 4, 5)

При желании можно воспользоваться функцией tuple().

>>> a = tuple((1, 2, 3, 4))
>>> print(a)
(1, 2, 3, 4)

Доступ к элементам кортежа

Доступ к элементам кортежа осуществляется также как к элементам списка – через указание индекса. Но, как уже было сказано – изменять элементы кортежа нельзя!

>>> a = (1, 2, 3, 4, 5)
>>> print(a[0])
1
>>> print(a[1:3])
(2, 3)
>>> a[1] = 3
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    a[1] = 3
TypeError: 'tuple' object does not support item assignment

Удаление кортежей

Удалить отдельные элементы из кортежа невозможно.

>>> a = (1, 2, 3, 4, 5)
>>> del a[0]
Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    del a[0]
TypeError: 'tuple' object doesn't support item deletion

Но можно удалить кортеж целиком.

>>> del a
>>> print(a)
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    print(a)
NameError: name 'a' is not defined

Преобразование кортежа в список и обратно

На базе кортежа можно создать список, верно и обратное утверждение. Для превращения списка в кортеж достаточно передать его в качестве аргумента функции tuple().

>>> lst = [1, 2, 3, 4, 5]
>>> print(type(lst))
<class 'list'>
>>> print(lst)
[1, 2, 3, 4, 5]
>>> tpl = tuple(lst)
>>> print(type(tpl))
<class 'tuple'>
>>> print(tpl)
(1, 2, 3, 4, 5)

Обратная операция также является корректной.

>>> tpl = (2, 4, 6, 8, 10)
>>> print(type(tpl))
<class 'tuple'>
>>> print(tpl)
(2, 4, 6, 8, 10)
>>> lst = list(tpl)
>>> print(type(lst))
<class 'list'>
>>> print(lst)
[2, 4, 6, 8, 10]

P.S.

Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. На нашем сайте вы можете найти вводные уроки по этой теме. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.
Книга: Pandas. Работа с данными

<<< Python. Урок 7. Работа со списками (list)   Python. Урок 9. Словари (dict)>>>

devpractice.ru

список и кортеж / Habr

В Python, есть два похожих типа — список (list) и кортеж (tuple). Самая известная разница между ними состоит в том, что кортежи неизменяемы.

Вы не можете изменить объекты в tuple:

>>> a = (1,2,3)
>>> a[0] = 10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Но вы можете модифицировать изменяемые объекты внутри кортежа:
>>> b = (1,[1,2,3],3)
>>> b[1]
[1, 2, 3]
>>> b[1].append(4)
>>> b
(1, [1, 2, 3, 4], 3)

Внутри CPython (стандартного интерпретатора), список и кортеж реализованы как лист из указателей (ссылок) на Python объекты, т.е. физически они не хранят объекты рядом с друг другом. Когда вы удаляете объект из списка происходит удаление ссылки на этот объект. Если на объект ещё кто-то ссылается, то он продолжит находиться в памяти.
Кортежи

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

Вы можете не замечать, но вы используете кортежи когда:

  • работаете с аргументами или параметрами (они хранятся как кортежи)
  • возвращаете две или более переменных из функции
  • итерируете ключи-значения в словаре
  • используете форматирование строк

Как правило, самый просто скрипт использует тысячи кортежей:
>>> import gc
>>> def type_stats(type_obj):
...     count = 0
...     for obj in gc.get_objects():
...         if type(obj) == type_obj:
...             count += 1
...     return count
...
>>> type_stats(tuple)
3136
>>> type_stats(list)
659
>>> import pandas
>>> type_stats(tuple)
6953
>>> type_stats(list)
2455

Пустые списки vs пустые кортежи

Пустой кортеж работает как синглтон, т.е. в памяти запущенного Python скрипта всегда находится только один пустой кортеж. Все пустые кортежи просто ссылаются на один и тот же объект, это возможно благодаря тому, что кортежи неизменяемы. Такой подход сохраняет много памяти и ускоряет процесс работы с пустыми кортежами.
>>> a = ()
>>> b = ()
>>> a is b
True
>>> id(a)
4409020488
>>> id(b)
4409020488
>>> # В CPython, функция id возвращает адрес в памяти.

Но это не работает со списками, ведь они могут быть изменены:
>>> a = []
>>> b = []
>>> a is b
False
>>> id(a)
4465566920
>>> id(b)
4465370632

Оптимизация выделения памяти для кортежей

Для того, чтобы снизить фрагментацию памяти и ускорить создание кортежей, Python переиспользует старые кортежи, которые были удалены. Если кортеж состоит из менее чем 20 элементов и больше не используется, то вместо удаления Python помещает его в специальный список, в котором хранятся свободные для повторного использования кортежи.

Этот список разделен на 20 групп, где каждая группа представляет из себя список кортежей размера n, где n от 0 до 20. Каждая группа может хранить до 2 000 свободных кортежей. Первая группа хранит только один элемент и представляет из себя список из одного пустого кортежа.

>>> a = (1,2,3)
>>> id(a)
4427578104
>>> del a
>>> b = (1,2,4)
>>> id(b)
4427578104

В примере выше, мы можем видеть, что a и b имеют одинаковый адрес в памяти. Это происходит из-за того, что мы мгновенно заняли свободный кортеж такого же размера.
Оптимизация выделения памяти для списков

Так как списки могут изменяться, такую же оптимизацию как в случае с кортежами провернуть уже не получится. Несмотря на это, для списков используется похожая оптимизация нацеленная на пустые списки. Если пустой список удаляется, то он так же может быть переиспользован в дальнейшем.
>>> a = []
>>> id(a)
4465566792
>>> del a
>>> b = []
>>> id(b)
4465566792

Изменение размера списка

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

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

Паттерн роста размера списка выглядит примерно так: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88,…

Для примера, если вы хотите добавить новый элемент в список с 8 элементами, то свободных ячеек в нём уже не будет и Python сразу расширит его размер до 16 ячеек, где 9 из них будут заняты и видны пользователю.

Формула выбора размера написанная на Python:

>>> def get_new_size(n_items):
...     new_size = n_items + (n_items // 2 ** 3)
...     if n_items < 9:
...             new_size += 3
...     else:
...             new_size += 6
...
...     return new_size
...
>>> get_new_size(9)
16

Скорость

Если сравнивать эти два типа по скорости, то в среднем по больнице, кортежи слегка быстрее списков. У Raymond Hettinger есть отличное объяснение разницы в скорости на stackoverflow.

P.S.: Я являюсь автором этой статьи, можете задавать любые вопросы.

habr.com

Отправить ответ

avatar
  Подписаться  
Уведомление о