Списки и кортежи в Python

Списки и кортежи в Python

Lists иtuples, возможно, наиболее универсальные и полезныеdata types для Python. Вы найдете их практически в каждой нетривиальной программе Python.

Here’s what you’ll learn in this tutorial: Вы расскажете о важных характеристиках списков и кортежей. Вы узнаете, как их определять и как ими манипулировать. Когда вы закончите, вы должны хорошо понимать, когда и как использовать эти типы объектов в программе Python.

__ Take the Quiz: Проверьте свои знания с помощью нашей интерактивной викторины «Списки и кортежи Python». По окончании вы получите оценку, чтобы вы могли отслеживать прогресс в обучении с течением времени:

Списки Python

Короче говоря, список - это набор произвольных объектов, несколько похожий на массив во многих других языках программирования, но более гибкий. Списки определяются в Python путем заключения последовательности объектов, разделенных запятыми, в квадратные скобки ([]), как показано ниже:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']

>>> print(a)
['foo', 'bar', 'baz', 'qux']
>>> a
['foo', 'bar', 'baz', 'qux']

Важными характеристиками списков Python являются следующие:

  • Списки упорядочены.

  • Списки могут содержать любые произвольные объекты.

  • Элементы списка могут быть доступны по индексу.

  • Списки могут быть вложены на произвольную глубину.

  • Списки изменчивы.

  • Списки являются динамическими.

Каждая из этих функций рассматривается более подробно ниже.

Списки заказаны

Список - это не просто набор объектов. Это упорядоченная коллекция предметов. Порядок, в котором вы указываете элементы при определении списка, является врожденной характеристикой этого списка и поддерживается в течение всего срока существования этого списка. (Вы увидите тип данных Python, который не упорядочен в следующем уроке по словарям.)

Списки с одинаковыми элементами в другом порядке не совпадают:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux']
>>> b = ['baz', 'qux', 'bar', 'foo']
>>> a == b
False
>>> a is b
False

>>> [1, 2, 3, 4] == [4, 1, 3, 2]
False

Списки могут содержать произвольные объекты

Список может содержать любой ассортимент объектов. Все элементы списка могут быть одного типа:

>>>

>>> a = [2, 4, 6, 8]
>>> a
[2, 4, 6, 8]

Или элементы могут быть разных типов:

>>>

>>> a = [21.42, 'foobar', 3, 4, 'bark', False, 3.14159]
>>> a
[21.42, 'foobar', 3, 4, 'bark', False, 3.14159]

Списки могут даже содержать сложные объекты, такие как функции, классы и модули, о которых вы узнаете в следующих уроках:

>>>

>>> int

>>> len

>>> def foo():
...     pass
...
>>> foo

>>> import math
>>> math


>>> a = [int, len, foo, math]
>>> a
[, , ,
]

Список может содержать любое количество объектов, от нуля до целого, сколько позволит память вашего компьютера:

>>>

>>> a = []
>>> a
[]

>>> a = [ 'foo' ]
>>> a
['foo']

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
... 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
... 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
... 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
... 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
97, 98, 99, 100]

(Список с одним объектом иногда называют одноэлементным списком.)

Объекты списка не должны быть уникальными. Данный объект может появляться в списке несколько раз:

>>>

>>> a = ['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']
>>> a
['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']

Элементы списка могут быть доступны по индексу

Доступ к отдельным элементам в списке можно получить с помощью индекса в квадратных скобках. Это в точности аналогично доступу к отдельным символам в строке. Индексирование списка начинается с нуля, как и для строк.

Рассмотрим следующий список:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

Индексы элементов вa показаны ниже:

Вот код Python для доступа к некоторым элементамa:

>>>

>>> a[0]
'foo'
>>> a[2]
'baz'
>>> a[5]
'corge'

Практически все, что касается индексации строк, работает аналогично для списков. Например, отрицательный индекс списка отсчитывается с конца списка:

>>>

>>> a[-1]
'corge'
>>> a[-2]
'quux'
>>> a[-5]
'bar'

Нарезка тоже работает. Еслиa является списком, выражениеa[m:n] возвращает частьa от индексаm до индексаn, но не включая его:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[2:5]
['baz', 'qux', 'quux']

Другие функции нарезки строк работают аналогично и для нарезки списков:

  • Можно указывать как положительные, так и отрицательные показатели:

    >>>

>>> a[-5:-2]
['bar', 'baz', 'qux']
>>> a[1:4]
['bar', 'baz', 'qux']
>>> a[-5:-2] == a[1:4]
True
  • Пропуск первого индекса запускает срез в начале списка, а пропуск второго индекса расширяет срез до конца списка:

    >>>

>>> print(a[:4], a[0:4])
['foo', 'bar', 'baz', 'qux'] ['foo', 'bar', 'baz', 'qux']
>>> print(a[2:], a[2:len(a)])
['baz', 'qux', 'quux', 'corge'] ['baz', 'qux', 'quux', 'corge']

>>> a[:4] + a[4:]
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[:4] + a[4:] == a
True
  • Вы можете указать шаг - положительный или отрицательный:

    >>>

>>> a[0:6:2]
['foo', 'baz', 'quux']
>>> a[1:6:2]
['bar', 'qux', 'corge']
>>> a[6:0:-2]
['corge', 'qux', 'bar']
  • Синтаксис обращения к списку работает так же, как и для строк:

    >>>

>>> a[::-1]
['corge', 'quux', 'qux', 'baz', 'bar', 'foo']
  • Синтаксис[:] работает для списков. Однако существует важное различие между тем, как эта операция работает со списком, и тем, как она работает со строкой.

    Еслиs - строка,s[:] возвращает ссылку на тот же объект:

    >>>

>>> s = 'foobar'
>>> s[:]
'foobar'
>>> s[:] is s
True

+ И наоборот, еслиa является списком,a[:] возвращает новый объект, который является копиейa:

+>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[:]
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[:] is a
False

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

  • Операторыin иnot in:

    >>>

>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> 'qux' in a
True
>>> 'thud' not in a
True
  • Операторы конкатенации (+) и репликации (*):

    >>>

>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a + ['grault', 'garply']
['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']
>>> a * 2
['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'foo', 'bar', 'baz',
'qux', 'quux', 'corge']
  • Функцииlen(),min() иmax():

    >>>

>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> len(a)
6
>>> min(a)
'bar'
>>> max(a)
'qux'

Не случайно строки и списки ведут себя одинаково. Оба они являются частными случаями более общего типа объекта, называемого итерируемым, с которым вы познакомитесь более подробно в следующем руководстве по определенной итерации.

Кстати, в каждом приведенном выше примере список всегда присваивается переменной до того, как над ней выполняется какая-либо операция. Но вы также можете оперировать литералом списка:

>>>

>>> ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][2]
'baz'

>>> ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1]
['corge', 'quux', 'qux', 'baz', 'bar', 'foo']

>>> 'quux' in ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
True

>>> ['foo', 'bar', 'baz'] + ['qux', 'quux', 'corge']
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> len(['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1])
6

В этом отношении вы можете сделать то же самое со строковым литералом:

>>>

>>> 'If Comrade Napoleon says it, it must be right.'[::-1]
'.thgir eb tsum ti ,ti syas noelopaN edarmoC fI'

Списки могут быть вложенными

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

Посмотрите на этот (по общему мнению) надуманный пример:

>>>

>>> x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
>>> x
['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']

Структура объекта, на которую ссылаетсяx, показана ниже:

x[0],x[2] иx[4] - это строки, каждая из которых состоит из одного символа:

>>>

>>> print(x[0], x[2], x[4])
a g j

Ноx[1] иx[3] - это подсписки:

>>>

>>> x[1]
['bb', ['ccc', 'ddd'], 'ee', 'ff']

>>> x[3]
['hh', 'ii']

Чтобы получить доступ к элементам в подсписке, просто добавьте дополнительный индекс:

>>>

>>> x[1]
['bb', ['ccc', 'ddd'], 'ee', 'ff']

>>> x[1][0]
'bb'
>>> x[1][1]
['ccc', 'ddd']
>>> x[1][2]
'ee'
>>> x[1][3]
'ff'

>>> x[3]
['hh', 'ii']
>>> print(x[3][0], x[3][1])
hh ii

x[1][1] - это еще один подсписок, поэтому добавление еще одного индекса дает доступ к его элементам:

>>>

>>> x[1][1]
['ccc', 'ddd']
>>> print(x[1][1][0], x[1][1][1])
ccc ddd

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

Весь обычный синтаксис в отношении индексов и секционирования также применим к подспискам:

>>>

>>> x[1][1][-1]
'ddd'
>>> x[1][1:3]
[[ccc', 'ddd'], 'ee']
>>> x[3][::-1]
['ii', 'hh']

Однако следует помнить, что операторы и функции применяются только к списку на указанном вами уровне и не являются рекурсивными. Рассмотрим, что происходит, когда вы запрашиваете длинуx с помощьюlen():

>>>

>>> x
['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
>>> len(x)
5

>>> x[0]
'a'
>>> x[1]
['bb', ['ccc', 'ddd'], 'ee', 'ff']
>>> x[2]
'g'
>>> x[3]
['hh', 'ii']
>>> x[4]
'j'

x имеет всего пять элементов - три строки и два подсписка. Отдельные элементы в подсписках не учитываются при определении длиныx.

Вы столкнетесь с аналогичной ситуацией при использовании оператораin:

>>>

>>> 'ddd' in x
False
>>> 'ddd' in x[1]
False
>>> 'ddd' in x[1][1]
True

'ddd' не является одним из элементов вx илиx[1]. Это только непосредственно элемент в подспискеx[1][1]. Отдельный элемент в подсписке не считается элементом родительского списка (ов).

Списки изменчивы

Большинство типов данных, с которыми вы сталкивались до сих пор, были атомарными. Целочисленные или плавающие объекты, например, являются примитивными единицами, которые не могут быть далее разбиты. Эти типы являются неизменяемыми, что означает, что они не могут быть изменены после назначения. Не имеет смысла думать об изменении значения целого числа. Если вы хотите другое целое число, вы просто назначаете другое.

Напротив, строковый тип является составным типом. Строки сводятся к меньшим частям - компонентам символов. Возможно, имеет смысл подумать об изменении символов в строке. Но ты не можешь. В Python строки также неизменны.

Список является первым изменяемым типом данных, с которым вы столкнулись. После создания списка элементы можно добавлять, удалять, перемещать и перемещать по желанию. Python предоставляет широкий спектр способов изменения списков.

Изменение значения одного списка

Одно значение в списке можно заменить индексированием и простым присваиванием:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[2] = 10
>>> a[-1] = 20
>>> a
['foo', 'bar', 10, 'qux', 'quux', 20]

Вы можете вспомнить из учебникаStrings and Character Data in Python, что вы не можете сделать это со строкой:

>>>

>>> s = 'foobarbaz'
>>> s[2] = 'x'
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'str' object does not support item assignment

Элемент списка можно удалить с помощью командыdel:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> del a[3]
>>> a
['foo', 'bar', 'baz', 'quux', 'corge']
Изменение нескольких значений списка

Что, если вы хотите изменить несколько смежных элементов в списке одновременно? Python позволяет это с помощью назначения среза, который имеет следующий синтаксис:

a[m:n] = 

Опять же, на данный момент, подумайте о повторяемости как список. Это назначение заменяет указанный фрагментa на<iterable>:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[1:4]
['bar', 'baz', 'qux']
>>> a[1:4] = [1.1, 2.2, 3.3, 4.4, 5.5]
>>> a
['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']
>>> a[1:6]
[1.1, 2.2, 3.3, 4.4, 5.5]
>>> a[1:6] = ['Bark!']
>>> a
['foo', 'Bark!', 'quux', 'corge']

Количество вставленных элементов не обязательно должно быть равно количеству замененных. Python просто увеличивает или сокращает список по мере необходимости.

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

>>>

>>> a = [1, 2, 3]
>>> a[1:2] = [2.1, 2.2, 2.3]
>>> a
[1, 2.1, 2.2, 2.3, 3]

Обратите внимание, что это не то же самое, что замена одного элемента списком:

>>>

>>> a = [1, 2, 3]
>>> a[1] = [2.1, 2.2, 2.3]
>>> a
[1, [2.1, 2.2, 2.3], 3]

Вы также можете вставлять элементы в список, не удаляя ничего. Просто укажите фрагмент формы[n:n] (фрагмент нулевой длины) по желаемому индексу:

>>>

>>> a = [1, 2, 7, 8]
>>> a[2:2] = [3, 4, 5, 6]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8]

Вы можете удалить несколько элементов из середины списка, назначив соответствующий фрагмент пустому списку. Вы также можете использовать операторdel с тем же срезом:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[1:5] = []
>>> a
['foo', 'corge']

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> del a[1:5]
>>> a
['foo', 'corge']
Добавление или добавление элементов в список

Дополнительные элементы могут быть добавлены в начало или конец списка с помощью оператора расширенного присваивания+` concatenation operator or the `=+:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a += ['grault', 'garply']
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a = [10, 20] + a
>>> a
[10, 20, 'foo', 'bar', 'baz', 'qux', 'quux', 'corge']

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

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a += 20
Traceback (most recent call last):
  File "", line 1, in 
    a += 20
TypeError: 'int' object is not iterable

>>> a += [20]
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 20]

Note: С технической точки зрения было бы не совсем правильно говорить, что список должен быть объединен с другим списком. Точнее, список должен быть объединен с объектом, который является итеративным. Конечно, списки являются итеративными, поэтому он работает для объединения списка с другим списком.

Строки также итеративны. Но посмотрите, что происходит, когда вы объединяете строку в список:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux']
>>> a += 'corge'
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'c', 'o', 'r', 'g', 'e']

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

Если вы действительно хотите добавить только одну строку'corge' в конец списка, вам нужно указать ее как одноэлементный список:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux']
>>> a += ['corge']
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

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

Методы, которые изменяют список

Наконец, Python предоставляет несколько встроенных методов, которые можно использовать для изменения списков. Информация об этих методах подробно описана ниже.

Note: Строковые методы, которые вы видели в предыдущем руководстве, не изменяли напрямую целевую строку. Это потому, что строки неизменны. Вместо этого строковые методы возвращают новый строковый объект, который изменяется в соответствии с указаниями метода. Они оставляют исходную целевую строку без изменений:

>>>

>>> s = 'foobar'
>>> t = s.upper()
>>> print(s, t)
foobar FOOBAR

Методы списка разные. Поскольку списки являются изменяемыми, методы списка, показанные здесь, изменяют целевой список на месте.

a.append()

Добавляет объект в список.

a.append(<obj>) добавляет объект<obj> в конец спискаa:

>>>

>>> a = ['a', 'b']
>>> a.append(123)
>>> a
['a', 'b', 123]

Помните, методы списка изменяют целевой список на месте. Они не возвращают новый список:

>>>

>>> a = ['a', 'b']
>>> x = a.append(123)
>>> print(x)
None
>>> a
['a', 'b', 123]

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

>>>

>>> a = ['a', 'b']
>>> a + [1, 2, 3]
['a', 'b', 1, 2, 3]

Метод.append() не работает! Если итерация добавляется к списку с помощью.append(), она добавляется как один объект:

>>>

>>> a = ['a', 'b']
>>> a.append([1, 2, 3])
>>> a
['a', 'b', [1, 2, 3]]

Таким образом, с помощью.append() вы можете добавить строку как единый объект:

>>>

>>> a = ['a', 'b']
>>> a.append('foo')
>>> a
['a', 'b', 'foo']

a.extend()

Расширяет список объектов из итерируемого.

Да, это, вероятно, то, что вы думаете. .extend() также добавляется в конец списка, но ожидается, что аргумент будет повторяемым. Элементы в<iterable> добавляются индивидуально:

>>>

>>> a = ['a', 'b']
>>> a.extend([1, 2, 3])
>>> a
['a', 'b', 1, 2, 3]

Другими словами,.extend() ведет себя как оператор+` operator. More precisely, since it modifies the list in place, it behaves like the `=+:

>>>

>>> a = ['a', 'b']
>>> a += [1, 2, 3]
>>> a
['a', 'b', 1, 2, 3]

a.insert(, )

Вставляет объект в список.

a.insert(<index>, <obj>) вставляет объект<obj> в списокa в указанный<index>. После вызова методаa[<index>] будет<obj>, а остальные элементы списка сдвинуты вправо:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a.insert(3, 3.14159)
>>> a[3]
3.14159
>>> a
['foo', 'bar', 'baz', 3.14159, 'qux', 'quux', 'corge']

a.remove()

Удаляет объект из списка.

a.remove(<obj>) удаляет объект<obj> из спискаa. Если<obj> отсутствует вa, возникает исключение:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a.remove('baz')
>>> a
['foo', 'bar', 'qux', 'quux', 'corge']

>>> a.remove('Bark!')
Traceback (most recent call last):
  File "", line 1, in 
    a.remove('Bark!')
ValueError: list.remove(x): x not in list

a.pop(index=-1)

Удаляет элемент из списка.

Этот метод отличается от.remove() двумя способами:

  1. Вы указываете индекс удаляемого элемента, а не сам объект.

  2. Метод возвращает значение: элемент, который был удален.

a.pop() просто удаляет последний элемент в списке:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a.pop()
'corge'
>>> a
['foo', 'bar', 'baz', 'qux', 'quux']

>>> a.pop()
'quux'
>>> a
['foo', 'bar', 'baz', 'qux']

Если указан необязательный параметр<index>, элемент с этим индексом удаляется и возвращается. <index> может быть отрицательным, как при индексировании строк и списков:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a.pop(1)
'bar'
>>> a
['foo', 'baz', 'qux', 'quux', 'corge']

>>> a.pop(-3)
'qux'
>>> a
['foo', 'baz', 'quux', 'corge']

<index> по умолчанию-1, поэтомуa.pop(-1) эквивалентноa.pop().

Списки динамичны

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

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[2:2] = [1, 2, 3]
>>> a += [3.14159]
>>> a
['foo', 'bar', 1, 2, 3, 'baz', 'qux', 'quux', 'corge', 3.14159]

Точно так же список сокращается, чтобы приспособиться к удалению элементов:

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[2:3] = []
>>> del a[0]
>>> a
['bar', 'qux', 'quux', 'corge']

Python Tuples

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

Произношение варьируется в зависимости от того, кого вы спрашиваете. Некоторые произносят его так, как если бы оно было написано «too-ple» (рифмуется с «Mott the Hoople»), а другие, как если бы оно было написано «tup-ple» (рифмуется с «symp»). Я склоняюсь к последнему, поскольку он предположительно происходит из того же происхождения, что и «пятерка», «шестикрат», «восьмикратный» и т. Д., И все, кого я знаю, произносят эти последние, как если бы они рифмовались с «податливым».

Определение и использование кортежей

Кортежи идентичны спискам во всех отношениях, за исключением следующих свойств:

  • Кортежи определяются заключением элементов в круглые скобки (()) вместо квадратных скобок ([]).

  • Кортежи неизменны.

Вот короткий пример, показывающий определение кортежа, индексацию и нарезку:

>>>

>>> t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')
>>> t
('foo', 'bar', 'baz', 'qux', 'quux', 'corge')

>>> t[0]
'foo'
>>> t[-1]
'corge'
>>> t[1::2]
('bar', 'qux', 'corge')

Не бойся! Наш любимый механизм реверсирования строк и списков работает и для кортежей:

>>>

>>> t[::-1]
('corge', 'quux', 'qux', 'baz', 'bar', 'foo')

Note: Несмотря на то, что кортежи определяются с помощью круглых скобок, вы по-прежнему индексируете и нарезаете кортежи с помощью квадратных скобок, как для строк и списков.

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

>>>

>>> t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')
>>> t[2] = 'Bark!'
Traceback (most recent call last):
  File "", line 1, in 
    t[2] = 'Bark!'
TypeError: 'tuple' object does not support item assignment

Зачем использовать кортеж вместо списка?

  • Выполнение программы быстрее при манипулировании кортежем, чем для эквивалентного списка. (Это, вероятно, не будет заметно, когда список или кортеж малы.)

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

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

В сеансе Python REPL вы можете отображать значения нескольких объектов одновременно, вводя их непосредственно в приглашении>>> через запятую:

>>>

>>> a = 'foo'
>>> b = 42
>>> a, 3.14159, b
('foo', 3.14159, 42)

Python отображает ответ в скобках, потому что он неявно интерпретирует входные данные как кортеж.

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

>>>

>>> t = ()
>>> type(t)

>>>

>>> t = (1, 2)
>>> type(t)

>>> t = (1, 2, 3, 4, 5)
>>> type(t)

Но что происходит, когда вы пытаетесь определить кортеж с одним элементом:

>>>

>>> t = (2)
>>> type(t)

Doh! Поскольку круглые скобки также используются для определения приоритета операторов в выражениях, Python оценивает выражение(2) как просто целое число2 и создает объектint. Чтобы сообщить Python, что вы действительно хотите определить одноэлементный кортеж, добавьте конечную запятую (,) непосредственно перед закрывающей круглой скобкой:

>>>

>>> t = (2,)
>>> type(t)

>>> t[0]
2
>>> t[-1]
2

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

Когда вы отображаете одноэлементный кортеж, Python включает запятую, чтобы напомнить вам, что это кортеж:

>>>

>>> print(t)
(2,)

Назначение, упаковка и распаковка кортежей

Как вы уже видели выше, буквальный кортеж, содержащий несколько элементов, может быть назначен одному объекту:

>>>

>>> t = ('foo', 'bar', 'baz', 'qux')

Когда это происходит, все элементы в кортеже «упакованы» в объект:

>>>

>>> t
('foo', 'bar', 'baz', 'qux')
>>> t[0]
'foo'
>>> t[-1]
'qux'

Если этот «упакованный» объект впоследствии назначается новому кортежу, отдельные элементы «распаковываются» в объекты в кортеже:

>>>

>>> (s1, s2, s3, s4) = t
>>> s1
'foo'
>>> s2
'bar'
>>> s3
'baz'
>>> s4
'qux'

При распаковке число переменных слева должно соответствовать количеству значений в кортеже:

>>>

>>> (s1, s2, s3) = t
Traceback (most recent call last):
  File "", line 1, in 
    (s1, s2, s3) = t
ValueError: too many values to unpack (expected 3)

>>> (s1, s2, s3, s4, s5) = t
Traceback (most recent call last):
  File "", line 1, in 
    (s1, s2, s3, s4, s5) = t
ValueError: not enough values to unpack (expected 5, got 4)

Упаковка и распаковка могут быть объединены в один оператор для составного присваивания:

>>>

>>> (s1, s2, s3, s4) = ('foo', 'bar', 'baz', 'qux')
>>> s1
'foo'
>>> s2
'bar'
>>> s3
'baz'
>>> s4
'qux'

Опять же, количество элементов в кортеже слева от присвоения должно равняться числу справа:

>>>

>>> (s1, s2, s3, s4, s5) = ('foo', 'bar', 'baz', 'qux')
Traceback (most recent call last):
  File "", line 1, in 
    (s1, s2, s3, s4, s5) = ('foo', 'bar', 'baz', 'qux')
ValueError: not enough values to unpack (expected 5, got 4)

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

>>>

>>> t = 1, 2, 3
>>> t
(1, 2, 3)

>>> x1, x2, x3 = t
>>> x1, x2, x3
(1, 2, 3)

>>> x1, x2, x3 = 4, 5, 6
>>> x1, x2, x3
(4, 5, 6)

>>> t = 2,
>>> t
(2,)

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

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

>>>

>>> a = 'foo'
>>> b = 'bar'
>>> a, b
('foo', 'bar')

>>># We need to define a temp variable to accomplish the swap.
>>> temp = a
>>> a = b
>>> b = temp

>>> a, b
('bar', 'foo')

В Python обмен может быть выполнен с помощью одного присваивания кортежа:

>>>

>>> a = 'foo'
>>> b = 'bar'
>>> a, b
('foo', 'bar')

>>># Magic time!
>>> a, b = b, a

>>> a, b
('bar', 'foo')

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

Заключение

В этом руководстве были рассмотрены основные свойства Pythonlists иtuples и способы управления ими. Вы будете широко использовать их в программировании на Python.

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

В следующем руководстве вы познакомитесь с неупорядоченным составным типом данных Pythondictionary:. Читать дальше!

__ Take the Quiz: Проверьте свои знания с помощью нашей интерактивной викторины «Списки и кортежи Python». По окончании вы получите оценку, чтобы вы могли отслеживать прогресс в обучении с течением времени: