Главная страница

ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов


Скачать 7.92 Mb.
НазваниеНиколай Прохоренок Владимир Дронов
Дата05.05.2023
Размер7.92 Mb.
Формат файлаpdf
Имя файлаПрохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен.pdf
ТипДокументы
#1111379
страница15 из 83
1   ...   11   12   13   14   15   16   17   18   ...   83

")) input()
Результат выполнения:


Метод subn()
аналогичен методу sub()
, но возвращает не строку, а кортеж из двух элемен- тов: измененной строки и количества произведенных замен. Метод имеет следующий фор- мат: subn(<Новый фрагмент или ссылка на функцию>, <Строка для замены>
[, <Максимальное количество замен>])
Заменим все числа в строке на
0
:
>>> p = re.compile(r"[0-9]+")
>>> p.subn("0", "2008, 2009, 2010, 2011")
('0, 0, 0, 0', 4)
Вместо метода subn()
можно воспользоваться функцией subn()
. Формат функции: re.subn(<Шаблон>, <Новый фрагмент или ссылка на функцию>,
<Строка для замены>[, <Максимальное количество замен>
[, flags=0]])

Глава 7. Регулярные выражения
139
В качестве параметра
<Шаблон>
можно указать строку с регулярным выражением или ском- пилированное регулярное выражение:
>>> p = r"200[79]"
>>> re.subn(p, "2001", "2007, 2008, 2009, 2010")
('2001, 2008, 2001, 2010', 2)
Для выполнения замен также можно использовать метод expand()
, поддерживаемый объек- том
Match
. Формат метода: expand(<Шаблон>)
Внутри указанного шаблона можно использовать обратные ссылки:
\номер группы
,
\g<номер группы>
и
\g<название группы>
:
>>> p = re.compile(r"<(?P[a-z]+)><(?P[a-z]+)>")
>>> m = p.search("

")
>>> m.expand(r"<\2><\1>") # \номер '

'
>>> m.expand(r"<\g<2>><\g<1>>") # \g<номер>
'

'
>>> m.expand(r"<\g><\g>") # \g<название>
'

'
7.5. Прочие функции и методы
Метод split()
разбивает строку по шаблону и возвращает список подстрок. Его формат: split(<Исходная строка>[, <Лимит>])
Если во втором параметре задано число, то в списке окажется указанное количество под- строк. Если подстрок больше указанного количества, то список будет содержать еще один элемент — с остатком строки:
>>> import re
>>> p = re.compile(r"[\s,.]+")
>>> p.split("word1, word2\nword3\r\nword4.word5")
['word1', 'word2', 'word3', 'word4', 'word5']
>>> p.split("word1, word2\nword3\r\nword4.word5", 2)
['word1', 'word2', 'word3\r\nword4.word5']
Если разделитель в строке не найден, список будет состоять только из одного элемента, содержащего исходную строку:
>>> p = re.compile(r"[0-9]+")
>>> p.split("word, word\nword")
['word, word\nword']
Вместо метода split()
можно воспользоваться функцией split()
. Формат функции: re.split(<Шаблон>, <Исходная строка>[, <Лимит>[, flags=0]])
В качестве параметра
<Шаблон>
можно указать строку с регулярным выражением или ском- пилированное регулярное выражение:
>>> p = re.compile(r"[\s,.]+")
>>> re.split(p, "word1, word2\nword3")
['word1', 'word2', 'word3']

140
Часть I. Основы языка Python
>>> re.split(r"[\s,.]+", "word1, word2\nword3")
['word1', 'word2', 'word3']
Функция escape(<Строка>)
экранирует все специальные символы в строке, после чего ее можно безопасно использовать внутри регулярного выражения:
>>> print(re.escape(r"[]().*"))
\[\]\(\)\.\*
Функция purge()
выполняет очистку кэша, в котором хранятся промежуточные данные, используемые в процессе выполнения регулярных выражений. Ее рекомендуется вызывать после обработки большого количества регулярных выражений. Результата эта функция не возвращает:
>>> re.purge()

ГЛ А В А
8
Списки, кортежи, множества и диапазоны
Списки, кортежи, множества и диапазоны — это нумерованные наборы объектов. Каж- дый элемент набора содержит лишь ссылку на объект — по этой причине они могут содер- жать объекты произвольного типа данных и иметь неограниченную степень вложенности.
Позиция элемента в наборе задается индексом. Обратите внимание на то, что нумерация элементов начинается с
0
, а не с
1
Списки и кортежи являются просто упорядоченными последовательностями элементов. Как и все последовательности, они поддерживают обращение к элементу по индексу, получение среза, конкатенацию (оператор
+
), повторение (оператор
*
), проверку на вхождение (оператор in
) и невхождение (оператор not in
).

Списки относятся к изменяемым типам данных. Это означает, что мы можем не только получить элемент по индексу, но и изменить его:
>>> arr = [1, 2, 3] # Создаем список
>>> arr[0] # Получаем элемент по индексу
1
>>> arr[0] = 50 # Изменяем элемент по индексу
>>> arr
[50, 2, 3]

Кортежи относятся к неизменяемым типам данных. Иными словами, можно получить элемент по индексу, но изменить его нельзя:
>>> t = (1, 2, 3) # Создаем кортеж
>>> t[0] # Получаем элемент по индексу
1
>>> t[0] = 50 # Изменить элемент по индексу нельзя!
Traceback (most recent call last):
File "
", line 1, in t[0] = 50 # Изменить элемент по индексу нельзя!
TypeError: 'tuple' object does not support item assignment

Множества могут быть как изменяемыми, так и неизменяемыми. Их основное отличие от только что рассмотренных типов данных — хранение лишь уникальных значений
(неуникальные значения автоматически отбрасываются):
>>> set([0, 1, 1, 2, 3, 3, 4])
{0, 1, 2, 3, 4}

142
Часть I. Основы языка Python

Что касается диапазонов, то они представляют собой наборы чисел, сформированные на основе заданных начального, конечного значений и величины шага между числами. Их важнейшее преимущество перед всеми остальными наборами объектов — небольшой объем занимаемой оперативной памяти:
>>> r = range(0, 101, 10)
>>> for i in r: print(i, end = " ")
0 10 20 30 40 50 60 70 80 90 100
Рассмотрим все упомянутые типы данных более подробно.
8.1. Создание списка
Создать список можно следующими способами:
 с помощью функции list([<Последовательность>])
. Функция позволяет преобразовать любую последовательность в список. Если параметр не указан, создается пустой список:
>>> list() # Создаем пустой список
[]
>>> list("String") # Преобразуем строку в список
['S', 't', 'r', 'i', 'n', 'g']
>>> list((1, 2, 3, 4, 5)) # Преобразуем кортеж в список
[1, 2, 3, 4, 5]
 указав все элементы списка внутри квадратных скобок:
>>> arr = [1, "str", 3, "4"]
>>> arr
[1, 'str', 3, '4']
 заполнив список поэлементно с помощью метода append()
:
>>> arr = [] # Создаем пустой список
>>> arr.append(1) # Добавляем элемент1 (индекс 0)
>>> arr.append("str") # Добавляем элемент2 (индекс 1)
>>> arr
[1, 'str']
В некоторых языках программирования (например, в PHP) можно добавить элемент, указав пустые квадратные скобки или индекс больше последнего индекса. В языке Python все эти способы приведут к ошибке:
>>> arr = []
>>> arr[] = 10
SyntaxError: invalid syntax
>>> arr[0] = 10
Traceback (most recent call last):
File "
", line 1, in arr[0] = 10
IndexError: list assignment index out of range
При создании списка в переменной сохраняется ссылка на объект, а не сам объект. Это обя- зательно следует учитывать при групповом присваивании. Групповое присваивание можно использовать для чисел и строк, но для списков этого делать нельзя. Рассмотрим пример:

Глава 8. Списки, кортежи, множества и диапазоны
143
>>> x = y = [1, 2] # Якобы создали два объекта
>>> x, y
([1, 2], [1, 2])
В этом примере мы создали список из двух элементов и присвоили значение переменным x
и y
. Теперь попробуем изменить значение в переменной y
:
>>> y[1] = 100 # Изменяем второй элемент
>>> x, y # Изменилось значение сразу в двух переменных
([1, 100], [1, 100])
Как видно из примера, изменение значения в переменной y
привело также к изменению значения в переменной x
. Таким образом, обе переменные ссылаются на один и тот же объ- ект, а не на два разных объекта. Чтобы получить два объекта, необходимо производить раз- дельное присваивание:
>>> x, y = [1, 2], [1, 2]
>>> y[1] = 100 # Изменяем второй элемент
>>> x, y
([1, 2], [1, 100])
Точно такая же ситуация возникает при использовании оператора повторения
*
. Например, в следующей инструкции производится попытка создания двух вложенных списков с по- мощью оператора
*
:
>>> arr = [ [] ] * 2 # Якобы создали два вложенных списка
>>> arr
[[], []]
>>> arr[0].append(5) # Добавляем элемент
>>> arr # Изменились два элемента
[[5], [5]]
Создавать вложенные списки следует с помощью метода append()
внутри цикла:
>>> arr = []
>>> for i in range(2): arr.append([])
>>> arr
[[], []]
>>> arr[0].append(5); arr
[[5], []]
Можно также воспользоваться генераторами списков:
>>> arr = [ [] for i in range(2) ]
>>> arr
[[], []]
>>> arr[0].append(5); arr
[[5], []]
Проверить, ссылаются ли две переменные на один и тот же объект, позволяет оператор is
Если переменные ссылаются на один и тот же объект, оператор is возвращает значение
True
:
>>> x = y = [1, 2] # Неправильно
>>> x is y # Переменные содержат ссылку на один и тот же список
True

144
Часть I. Основы языка Python
>>> x, y = [1, 2], [1, 2] # Правильно
>>> x is y # Это разные объекты
False
Но что же делать, если необходимо создать копию списка? Первый способ заключается в применении операции извлечения среза, второй — в использовании функции list()
, а третий — в вызове метода copy()
:
>>> x = [1, 2, 3, 4, 5] # Создали список
>>> # Создаем копию списка
>>> y = list(x) # или с помощью среза: y = x[:]
>>> # или вызовом метода copy(): y = x.copy()
>>> y
[1, 2, 3, 4, 5]
>>> x is y # Оператор показывает, что это разные объекты
False
>>> y[1] = 100 # Изменяем второй элемент
>>> x, y # Изменился только список в переменной y
([1, 2, 3, 4, 5], [1, 100, 3, 4, 5])
На первый взгляд может показаться, что мы получили копию — оператор is показывает, что это разные объекты, а изменение элемента затронуло лишь значение переменной y
В данном случае вроде все нормально. Но проблема заключается в том, что списки в языке
Python могут иметь неограниченную степень вложенности. Рассмотрим это на примере:
>>> x = [1, [2, 3, 4, 5]] # Создали вложенный список
>>> y = list(x) # Якобы сделали копию списка
>>> x is y # Разные объекты
False
>>> y[1][1] = 100 # Изменяем элемент
>>> x, y # Изменение затронуло переменную x!!!
([1, [2, 100, 4, 5]], [1, [2, 100, 4, 5]])
Здесь мы создали список, в котором второй элемент является вложенным списком, после чего с помощью функции list()
попытались создать копию списка. Как и в предыдущем примере, оператор is показывает, что это разные объекты, но посмотрите на результат — изменение переменной y
затронуло и значение переменной x
. Таким образом, функция list()
и операция извлечения среза создают лишь поверхностную копию списка.
Чтобы получить полную копию списка, следует воспользоваться функцией deepcopy()
из модуля copy
:
>>> import copy # Подключаем модуль copy
>>> x = [1, [2, 3, 4, 5]]
>>> y = copy.deepcopy(x) # Делаем полную копию списка
>>> y[1][1] = 100 # Изменяем второй элемент
>>> x, y # Изменился только список в переменной y
([1, [2, 3, 4, 5]], [1, [2, 100, 4, 5]])
Функция deepcopy()
создает копию каждого объекта, при этом сохраняя внутреннюю структуру списка. Иными словами, если в списке существуют два элемента, ссылающиеся на один объект, то будет создана копия объекта, и элементы будут ссылаться на этот новый объект, а не на разные объекты:
>>> import copy # Подключаем модуль copy
>>> x = [1, 2]

Глава 8. Списки, кортежи, множества и диапазоны
145
>>> y = [x, x] # Два элемента ссылаются на один объект
>>> y
[[1, 2], [1, 2]]
>>> z = copy.deepcopy(y) # Сделали копию списка
>>> z[0] is x, z[1] is x, z[0] is z[1]
(False, False, True)
>>> z[0][0] = 300 # Изменили один элемент
>>> z # Значение изменилось сразу в двух элементах!
[[300, 2], [300, 2]]
>>> x # Начальный список не изменился
[1, 2]
8.2. Операции над списками
Обращение к элементам списка осуществляется с помощью квадратных скобок, в которых указывается индекс элемента. Нумерация элементов списка начинается с нуля. Выведем все элементы списка:
>>> arr = [1, "str", 3.2, "4"]
>>> arr[0], arr[1], arr[2], arr[3]
(1, 'str', 3.2, '4')
С помощью позиционного присваивания можно присвоить значения элементов списка каким-либо переменным. Количество элементов справа и слева от оператора
=
должно сов- падать, иначе будет выведено сообщение об ошибке:
>>> x, y, z = [1, 2, 3] # Позиционное присваивание
>>> x, y, z
(1, 2, 3)
>>> x, y = [1, 2, 3] # Количество элементов должно совпадать
Traceback (most recent call last):
File "
", line 1, in x, y = [1, 2, 3] # Количество элементов должно совпадать
ValueError: too many values to unpack (expected 2)
В Python 3 при позиционном присваивании перед одной из переменных слева от операто- ра
=
можно указать звездочку. В этой переменной будет сохраняться список, состоящий из
«лишних» элементов. Если таких элементов нет, список будет пустым:
>>> x, y, *z = [1, 2, 3]; x, y, z
(1, 2, [3])
>>> x, y, *z = [1, 2, 3, 4, 5]; x, y, z
(1, 2, [3, 4, 5])
>>> x, y, *z = [1, 2]; x, y, z
(1, 2, [])
>>> *x, y, z = [1, 2]; x, y, z
([], 1, 2)
>>> x, *y, z = [1, 2, 3, 4, 5]; x, y, z
(1, [2, 3, 4], 5)
>>> *z, = [1, 2, 3, 4, 5]; z
[1, 2, 3, 4, 5]

146
Часть I. Основы языка Python
Так как нумерация элементов списка начинается с
0
, индекс последнего элемента будет на единицу меньше количества элементов. Получить количество элементов списка позволяет функция len()
:
>>> arr = [1, 2, 3, 4, 5]
>>> len(arr) # Получаем количество элементов
5
>>> arr[len(arr)-1] # Получаем последний элемент
5
Если элемент, соответствующий указанному индексу, отсутствует в списке, возбуждается исключение
IndexError
:
>>> arr = [1, 2, 3, 4, 5]
>>> arr[5] # Обращение к несуществующему элементу
Traceback (most recent call last):
File "
", line 1, in arr[5] # Обращение к несуществующему элементу
IndexError: list index out of range
В качестве индекса можно указать отрицательное значение. В этом случае смещение будет отсчитываться от конца списка, а точнее — чтобы получить положительный индекс, значе- ние вычитается из общего количества элементов списка:
>>> arr = [1, 2, 3, 4, 5]
>>> arr[-1], arr[len(arr)-1] # Обращение к последнему элементу
(5, 5)
Так как списки относятся к изменяемым типам данных, мы можем изменить элемент по индексу:
>>> arr = [1, 2, 3, 4, 5]
>>> arr[0] = 600 # Изменение элемента по индексу
>>> arr
[600, 2, 3, 4, 5]
Кроме того, списки поддерживают операцию извлечения среза, которая возвращает указан- ный фрагмент списка. Формат операции:
[<Начало>:<Конец>:<Шаг>]
Все параметры не являются обязательными. Если параметр
<Начало>
не указан, использует- ся значение
0
. Если параметр
<Конец>
не указан, возвращается фрагмент до конца списка.
Следует также заметить, что элемент с индексом, указанным в этом параметре, не входит в возвращаемый фрагмент. Если параметр
<Шаг>
не указан, используется значение
1
. В ка- честве значения параметров можно указать отрицательные значения.
Теперь рассмотрим несколько примеров:
 сначала получим поверхностную копию списка:
>>> arr = [1, 2, 3, 4, 5]
>>> m = arr[:]; m # Создаем поверхностную копию и выводим значения
[1, 2, 3, 4, 5]
>>> m is arr # Оператор is показывает, что это разные объекты
False

Глава 8. Списки, кортежи, множества и диапазоны
147
 затем выведем символы в обратном порядке:
>>> arr = [1, 2, 3, 4, 5]
>>> arr[::-1] # Шаг -1
[5, 4, 3, 2, 1]
 выведем список без первого и последнего элементов:
>>> arr[1:] # Без первого элемента
[2, 3, 4, 5]
>>> arr[:-1] # Без последнего элемента
[1, 2, 3, 4]
 получим первые два элемента списка:
>>> arr[0:2] # Символ с индексом 2 не входит в диапазон
[1, 2]
 а так получим последний элемент:
>>> arr[-1:] # Последний элемент списка
[5]
 и, наконец, выведем фрагмент от второго элемента до четвертого включительно:
>>> arr[1:4] # Возвращаются элементы с индексами 1, 2 и 3
[2, 3, 4]
С помощью среза можно изменить фрагмент списка. Если срезу присвоить пустой список, то элементы, попавшие в срез, будут удалены:
>>> arr = [1, 2, 3, 4, 5]
>>> arr[1:3] = [6, 7] # Изменяем значения элементов с индексами 1 и 2
>>> arr
[1, 6, 7, 4, 5]
>>> arr[1:3] = [] # Удаляем элементы с индексами 1 и 2
>>> arr
[1, 4, 5]
Объединить два списка в один список позволяет оператор
+
. Результатом объединения будет новый список:
>>> arr1 = [1, 2, 3, 4, 5]
>>> arr2 = [6, 7, 8, 9]
>>> arr3 = arr1 + arr2
>>> arr3
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Вместо оператора
+
можно использовать оператор
+=
. Следует учитывать, что в этом случае элементы добавляются в текущий список:
>>> arr = [1, 2, 3, 4, 5]
>>> arr += [6, 7, 8, 9]
>>> arr
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Кроме рассмотренных операций, списки поддерживают операцию повторения и проверку на вхождение. Повторить список указанное количество раз можно с помощью оператора
*
, а выполнить проверку на вхождение элемента в список позволяет оператор in
:

148
Часть I. Основы языка Python
>>> [1, 2, 3] * 3 # Операция повторения
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 2 in [1, 2, 3, 4, 5], 6 in [1, 2, 3, 4, 5] # Проверка на вхождение
(True, False)
8.3. Многомерные списки
Любой элемент списка может содержать объект произвольного типа. Например, элемент списка может быть числом, строкой, списком, кортежем, словарем и т. д. Создать вложен- ный список можно, например, так:
>>> arr = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
Как вы уже знаете, выражение внутри скобок может располагаться на нескольких строках.
Следовательно, предыдущий пример можно записать иначе:
>>> arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
Чтобы получить значение элемента во вложенном списке, следует указать два индекса:
>>> arr[1][1]
5
Элементы вложенного списка также могут иметь элементы произвольного типа. Количество вложений не ограничено, и мы можем создать объект любой степени сложности. В этом случае для доступа к элементам указывается несколько индексов подряд:
>>> arr = [ [1, ["a", "b"], 3], [4, 5, 6], [7, 8, 9] ]
>>> arr[0][1][0]
'a'
>>> arr = [ [1, { "a": 10, "b": ["s", 5] } ] ]
>>> arr[0][1]["b"][0]
's'
8.4. Перебор элементов списка
Перебрать все элементы списка можно с помощью цикла for
:
>>> arr = [1, 2, 3, 4, 5]
>>> for i in arr: print(i, end=" ")
1 2 3 4 5
Следует заметить, что переменную i
внутри цикла можно изменить, но если она ссылается на неизменяемый тип данных (например, на число или строку), это не отразится на исход- ном списке:
>>> arr = [1, 2, 3, 4] # Элементы имеют неизменяемый тип (число)
>>> for i in arr: i += 10
>>> arr # Список не изменился
[1, 2, 3, 4]

Глава 8. Списки, кортежи, множества и диапазоны
149
>>> arr = [ [1, 2], [3, 4] ] # Элементы имеют изменяемый тип (список)
>>> for i in arr: i[0] += 10
>>> arr # Список изменился
[[11, 2], [13, 4]]
Для генерации индексов элементов можно воспользоваться функцией range()
, которая воз- вращает объект-диапазон, поддерживающий итерации. С помощью такого диапазона внут- ри цикла for можно получить текущий индекс. Функция range()
имеет следующий формат: range([<Начало>, ]<Конец>[, <Шаг>])
Первый параметр задает начальное значение. Если он не указан, используется значение
0
Во втором параметре указывается конечное значение. Следует заметить, что это значение не входит в возвращаемый диапазон значений. Если параметр
<Шаг>
не указан, используется значение
1
. Для примера умножим каждый элемент списка на 2: arr = [1, 2, 3, 4] for i in range(len(arr)): arr[i] *= 2 print(arr) # Результат выполнения: [2, 4, 6, 8]
Можно также воспользоваться функцией enumerate(<Объект>[, start=0])
, которая на каж- дой итерации цикла for возвращает кортеж из индекса и значения текущего элемента спи- ска. Умножим каждый элемент списка на 2: arr = [1, 2, 3, 4] for i, elem in enumerate(arr): arr[i] *= 2 print(arr) # Результат выполнения: [2, 4, 6, 8]
Кроме того, перебрать элементы можно с помощью цикла while
, но нужно помнить, что он выполняется медленнее цикла for
. Для примера умножим каждый элемент списка на 2, ис- пользуя цикл while
: arr = [1, 2, 3, 4] i, c = 0, len(arr) while i < c: arr[i] *= 2 i += 1 print(arr) # Результат выполнения: [2, 4, 6, 8]
8.5. Генераторы списков и выражения-генераторы
В предыдущем разделе мы изменяли элементы списка следующим образом: arr = [1, 2, 3, 4] for i in range(len(arr)): arr[i] *= 2 print(arr) # Результат выполнения: [2, 4, 6, 8]
С помощью генераторов списков тот же самый код можно записать более компактно, к то- му же генераторы списков работают быстрее цикла for
. Однако вместо изменения исходно- го списка возвращается новый список: arr = [1, 2, 3, 4] arr = [ i * 2 for i in arr ] print(arr) # Результат выполнения: [2, 4, 6, 8]

150
Часть I. Основы языка Python
Как видно из примера, мы поместили цикл for внутри квадратных скобок, а также измени- ли порядок следования параметров, — инструкция, выполняемая внутри цикла, находится перед циклом. Обратите внимание и на то, что выражение внутри цикла не содержит опера- тора присваивания, — на каждой итерации цикла будет генерироваться новый элемент, которому неявным образом присваивается результат выполнения выражения внутри цикла.
В итоге будет создан новый список, содержащий измененные значения элементов исходного списка.
Генераторы списков могут иметь сложную структуру — например, состоять из нескольких вложенных циклов for и (или) содержать оператор ветвления if после цикла. Для примера получим четные элементы списка и умножим их на 10: arr = [1, 2, 3, 4] arr = [ i * 10 for i in arr if i % 2 == 0 ] print(arr) # Результат выполнения: [20, 40]
Этот код эквивалентен коду: arr = [] for i in [1, 2, 3, 4]: if i % 2 == 0: # Если число четное arr.append(i * 10) # Добавляем элемент print(arr) # Результат выполнения: [20, 40]
Усложним наш пример — получим четные элементы вложенного списка и умножим их на 10: arr = [[1, 2], [3, 4], [5, 6]] arr = [ j * 10 for i in arr for j in i if j % 2 == 0 ] print(arr) # Результат выполнения: [20, 40, 60]
Этот код эквивалентен коду: arr = [] for i in [[1, 2], [3, 4], [5, 6]]: for j in i: if j % 2 == 0: # Если число четное arr.append(j * 10) # Добавляем элемент print(arr) # Результат выполнения: [20, 40, 60]
Если выражение разместить внутри не квадратных, а круглых скобок, то будет возвращать- ся не список, а итератор. Такие конструкции называются выражениями-генераторами.
В качестве примера просуммируем четные числа в списке:
>>> arr = [1, 4, 12, 45, 10]
>>> sum((i for i in arr if i % 2 == 0))
26 8.6. Функции map(), zip(), filter() и reduce()
Встроенная функция map()
позволяет применить заданную в параметре функцию к каждому элементу последовательности. Она имеет такой формат: map(<Функция>, <Последовательность1>[, ..., <ПоследовательностьN>])
Функция map()
возвращает объект, поддерживающий итерации (а не список, как это было ранее в Python 2). Чтобы получить список в версии Python 3, возвращенный результат необ- ходимо передать в функцию list()

Глава 8. Списки, кортежи, множества и диапазоны
151
В качестве параметра
<Функция>
указывается ссылка на функцию (название функции без круглых скобок), которой будет передаваться текущий элемент последовательности. Внут- ри этой функции необходимо вернуть новое значение. Для примера прибавим к каждому элементу списка число 10 (листинг 8.1).
Листинг 8.1. Функция map() def func(elem):
""" Увеличение значения каждого элемента списка """ return elem + 10 # Возвращаем новое значение arr = [1, 2, 3, 4, 5] print( list( map(func, arr) ) )
# Результат выполнения: [11, 12, 13, 14, 15]
Функции map()
можно передать несколько последовательностей. В этом случае в функцию обратного вызова будут передаваться сразу несколько элементов, расположенных в после- довательностях на одинаковом смещении. Просуммируем элементы трех списков (лис- тинг 8.2).
Листинг 8.2. Суммирование элементов трех списков def func(e1, e2, e3):
""" Суммирование элементов трех разных списков """ return e1 + e2 + e3 # Возвращаем новое значение arr1 = [1, 2, 3, 4, 5] arr2 = [10, 20, 30, 40, 50] arr3 = [100, 200, 300, 400, 500] print( list( map(func, arr1, arr2, arr3) ) )
# Результат выполнения: [111, 222, 333, 444, 555]
Если количество элементов в последовательностях различается, за основу выбирается по- следовательность с минимальным количеством элементов (листинг 8.3).
Листинг 8.3. Суммирование элементов трех списков разной длины def func(e1, e2, e3):
""" Суммирование элементов трех разных списков """ return e1 + e2 + e3 arr1 = [1, 2, 3, 4, 5] arr2 = [10, 20] arr3 = [100, 200, 300, 400, 500] print( list( map(func, arr1, arr2, arr3) ) )
# Результат выполнения: [111, 222]
Встроенная функция zip()
на каждой итерации возвращает кортеж, содержащий элементы последовательностей, которые расположены на одинаковом смещении. Функция возвраща-

152
Часть I. Основы языка Python ет объект, поддерживающий итерации (а не список, как это было ранее в Python 2). Чтобы получить список в версии Python 3, необходимо результат передать в функцию list()
Формат функции: zip(<Последовательность1>[, ..., <ПоследовательностьN>])
Пример:
>>> zip([1, 2, 3], [4, 5, 6], [7, 8, 9])

>>> list(zip([1, 2, 3], [4, 5, 6], [7, 8, 9]))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Если количество элементов в последовательностях будет разным, то в результат попадут только элементы, которые существуют во всех последовательностях на одинаковом смеще- нии:
>>> list(zip([1, 2, 3], [4, 6], [7, 8, 9, 10]))
[(1, 4, 7), (2, 6, 8)]
В качестве еще одного примера переделаем нашу программу суммирования элементов трех списков (см. листинг 8.3) и используем функцию zip()
вместо функции map()
(листинг 8.4).
Листинг 8.4. Суммирование элементов трех списков с помощью функции zip() arr1 = [1, 2, 3, 4, 5] arr2 = [10, 20, 30, 40, 50] arr3 = [100, 200, 300, 400, 500] arr = [x + y + z for (x, y, z) in zip(arr1, arr2, arr3)] print(arr)
# Результат выполнения: [111, 222, 333, 444, 555]
Функция filter()
позволяет выполнить проверку элементов последовательности. Формат функции: filter(<Функция>, <Последовательность>)
Если в первом параметре вместо названия функции указать значение
None
, то каждый эле- мент последовательности будет проверен на соответствие значению
True
. Если элемент в логическом контексте возвращает значение
False
, то он не будет добавлен в возвращаемый результат. Функция возвращает объект, поддерживающий итерации (а не список или кор- теж, как это было ранее в Python 2). Чтобы получить список в версии Python 3, необходимо результат передать в функцию list()
:
>>> filter(None, [1, 0, None, [], 2])

>>> list(filter(None, [1, 0, None, [], 2]))
[1, 2]
Аналогичная операция с использованием генераторов списков выглядит так:
>>> [ i for i in [1, 0, None, [], 2] if i ]
[1, 2]
В первом параметре можно указать ссылку на функцию, в которую в качестве параметра будет передаваться текущий элемент последовательности. Если элемент нужно добавить

Глава 8. Списки, кортежи, множества и диапазоны
153 в возвращаемое функцией filter()
значение, то внутри функции, указанной в качестве первого параметра, следует вернуть значение
True
, в противном случае — значение
False
Для примера удалим все отрицательные значения из списка (листинг 8.5).
Листинг 8.5. Пример использования функции filter() def func(elem): return elem >= 0 arr = [-1, 2, -3, 4, 0, -20, 10] arr = list(filter(func, arr)) print(arr) # Результат: [2, 4, 0, 10]
# Использование генераторов списков arr = [-1, 2, -3, 4, 0, -20, 10] arr = [ i for i in arr if func(i) ] print(arr) # Результат: [2, 4, 0, 10]
Функция reduce()
из модуля functools применяет указанную функцию к парам элементов и накапливает результат. Функция имеет следующий формат: reduce(<Функция>, <Последовательность>[, <Начальное значение>])
В параметр
<Функция>
в качестве параметров передаются два элемента: первый элемент будет содержать результат предыдущих вычислений, а второй — значение текущего эле- мента. Получим сумму всех элементов списка (листинг 8.6).
Листинг 8.6. Пример использования функции reduce() from functools import reduce # Подключаем модуль def func(x, y): print("({0}, {1})".format(x, y), end=" ") return x + y arr = [1, 2, 3, 4, 5] summa = reduce(func, arr)
# Последовательность: (1, 2) (3, 3) (6, 4) (10, 5) print(summa) # Результат выполнения: 15 summa = reduce(func, arr, 10)
# Последовательность: (10, 1) (11, 2) (13, 3) (16, 4) (20, 5) print(summa) # Результат выполнения: 25 summa = reduce(func, [], 10) print(summa) # Результат выполнения: 10 8.7. Добавление и удаление элементов списка
Для добавления и удаления элементов списка используются следующие методы:
 append(<Объект>)
— добавляет один объект в конец списка. Метод изменяет текущий список и ничего не возвращает:

154
Часть I. Основы языка Python
>>> arr = [1, 2, 3]
>>> arr.append(4); arr # Добавляем число
[1, 2, 3, 4]
>>> arr.append([5, 6]); arr # Добавляем список
[1, 2, 3, 4, [5, 6]]
>>> arr.append((7, 8)); arr # Добавляем кортеж
[1, 2, 3, 4, [5, 6], (7, 8)]
 extend(<Последовательность>)
— добавляет элементы последовательности в конец списка. Метод изменяет текущий список и ничего не возвращает:
>>> arr = [1, 2, 3]
>>> arr.extend([4, 5, 6]) # Добавляем список
>>> arr.extend((7, 8, 9)) # Добавляем кортеж
>>> arr.extend("abc") # Добавляем буквы из строки
>>> arr
[1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c']
Добавить несколько элементов можно с помощью операции конкатенации или операто- ра
+=
:
>>> arr = [1, 2, 3]
>>> arr + [4, 5, 6] # Возвращает новый список
[1, 2, 3, 4, 5, 6]
>>> arr += [4, 5, 6] # Изменяет текущий список
>>> arr
[1, 2, 3, 4, 5, 6]
Кроме того, можно воспользоваться операцией присваивания значения срезу:
>>> arr = [1, 2, 3]
>>> arr[len(arr):] = [4, 5, 6] # Изменяет текущий список
>>> arr
[1, 2, 3, 4, 5, 6]
 insert(<Индекс>, <Объект>)
— добавляет один объект в указанную позицию. Осталь- ные элементы смещаются. Метод изменяет текущий список и ничего не возвращает:
>>> arr = [1, 2, 3]
>>> arr.insert(0, 0); arr # Вставляем 0 в начало списка
[0, 1, 2, 3]
>>> arr.insert(-1, 20); arr # Можно указать отрицательные числа
[0, 1, 2, 20, 3]
>>> arr.insert(2, 100); arr # Вставляем 100 в позицию 2
[0, 1, 100, 2, 20, 3]
>>> arr.insert(10, [4, 5]); arr # Добавляем список
[0, 1, 100, 2, 20, 3, [4, 5]]
Метод insert()
позволяет добавить только один объект. Чтобы добавить несколько объектов, можно воспользоваться операцией присваивания значения срезу. Добавим несколько элементов в начало списка:
>>> arr = [1, 2, 3]
>>> arr[:0] = [-2, -1, 0]
>>> arr
[-2, -1, 0, 1, 2, 3]

Глава 8. Списки, кортежи, множества и диапазоны
155
 pop([<Индекс>])
— удаляет элемент, расположенный по указанному индексу, и воз- вращает его. Если индекс не указан, то удаляет и возвращает последний элемент списка.
Если элемента с указанным индексом нет, или список пустой, возбуждается исключение
IndexError
:
>>> arr = [1, 2, 3, 4, 5]
>>> arr.pop() # Удаляем последний элемент списка
5
>>> arr # Список изменился
[1, 2, 3, 4]
>>> arr.pop(0) # Удаляем первый элемент списка
1
>>> arr # Список изменился
[2, 3, 4]
Удалить элемент списка позволяет также оператор del
:
>>> arr = [1, 2, 3, 4, 5]
>>> del arr[4]; arr # Удаляем последний элемент списка
[1, 2, 3, 4]
>>> del arr[:2]; arr # Удаляем первый и второй элементы
[3, 4]
 remove(<Значение>)
— удаляет первый элемент, содержащий указанное значение. Если элемент не найден, возбуждается исключение
ValueError
. Метод изменяет текущий спи- сок и ничего не возвращает:
>>> arr = [1, 2, 3, 1, 1]
>>> arr.remove(1) # Удаляет только первый элемент
>>> arr
[2, 3, 1, 1]
>>> arr.remove(5) # Такого элемента нет
Traceback (most recent call last):
File "
", line 1, in arr.remove(5) # Такого элемента нет
ValueError: list.remove(x): x not in list
 clear()
— удаляет все элементы списка, очищая его. Никакого результата при этом не возвращается:
>>> arr = [1, 2, 3, 1, 1]
>>> arr.clear()
>>> arr
[]
Если необходимо удалить все повторяющиеся элементы списка, то можно преобразовать список во множество, а затем множество обратно преобразовать в список. Обратите внима- ние на то, что список должен содержать только неизменяемые объекты (например, числа, строки или кортежи). В противном случае возбуждается исключение
TypeError
:
>>> arr = [1, 2, 3, 1, 1, 2, 2, 3, 3]
>>> s = set(arr) # Преобразуем список во множество
>>> s
{1, 2, 3}
>>> arr = list(s) # Преобразуем множество в список
>>> arr # Все повторы были удалены
[1, 2, 3]

156
Часть I. Основы языка Python
8.8. Поиск элемента в списке и получение сведений о значениях, входящих в список
Как вы уже знаете, выполнить проверку на вхождение элемента в список позволяет опера- тор in
: если элемент входит в список, то возвращается значение
True
, в противном слу- чае —
False
. Аналогичный оператор not in выполняет проверку на невхождение элемента в список: если элемент отсутствует в списке, возвращается
True
, в противном случае —
False
:
>>> 2 in [1, 2, 3, 4, 5], 6 in [1, 2, 3, 4, 5] # Проверка на вхождение
(True, False)
>>> 2 not in [1, 2, 3, 4, 5], 6 not in [1, 2, 3, 4, 5] # Проверка на невхождение
(False, True)
Тем не менее оба этих оператора не дают никакой информации о местонахождении элемен- та внутри списка. Чтобы узнать индекс элемента внутри списка, следует воспользоваться методом index()
. Формат метода: index(<Значение>[, <Начало>[, <Конец>]])
Метод index()
возвращает индекс элемента, имеющего указанное значение. Если значение не входит в список, то возбуждается исключение
ValueError
. Если второй и третий пара- метры не указаны, поиск будет производиться с начала и до конца списка:
>>> arr = [1, 2, 1, 2, 1]
>>> arr.index(1), arr.index(2)
(0, 1)
>>> arr.index(1, 1), arr.index(1, 3, 5)
(2, 4)
>>> arr.index(3)
Traceback (most recent call last):
File "
", line 1, in arr.index(3)
ValueError: 3 is not in list
Узнать общее количество элементов с указанным значением позволяет метод count(<Значение>)
. Если элемент не входит в список, возвращается значение
0
:
>>> arr = [1, 2, 1, 2, 1]
>>> arr.count(1), arr.count(2)
(3, 2)
>>> arr.count(3) # Элемент не входит в список
0
С помощью функций max()
и min()
можно узнать максимальное и минимальное значение из всех, что входят в список, соответственно:
>>> arr = [1, 2, 3, 4, 5]
>>> max(arr), min(arr)
(5, 1)
Функция any(<Последовательность>)
возвращает значение
True
, если в последовательности существует хотя бы один элемент, который в логическом контексте возвращает значение
True
. Если последовательность не содержит элементов, возвращается значение
False
:
>>> any([0, None]), any([0, None, 1]), any([])
(False, True, False)

Глава 8. Списки, кортежи, множества и диапазоны
157
Функция all(<Последовательность>)
возвращает значение
True
, если все элементы после- довательности в логическом контексте возвращают значение
True или последовательность не содержит элементов:
>>> all([0, None]), all([0, None, 1]), all([]), all(["str", 10])
(False, False, True, True)
8.9. Переворачивание и перемешивание списка
Метод reverse()
изменяет порядок следования элементов списка на противоположный.
Метод изменяет текущий список и ничего не возвращает:
>>> arr = [1, 2, 3, 4, 5]
>>> arr.reverse() # Изменяется текущий список
>>> arr
[5, 4, 3, 2, 1]
Если необходимо изменить порядок следования и получить новый список, следует восполь- зоваться функцией reversed(<Последовательность>)
. Она возвращает итератор, который можно преобразовать в список с помощью функции list()
или генератора списков:
>>> arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> reversed(arr)

>>> list(reversed(arr)) # Использование функции list()
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> for i in reversed(arr): print(i, end=" ") # Вывод с помощью цикла
10 9 8 7 6 5 4 3 2 1
>>> [i for i in reversed(arr)] # Использование генератора списков
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Функция shuffle(<Список>[, <Число от 0.0 до 1.0>])
из модуля random перемешивает список случайным образом. Функция перемешивает сам список и ничего не возвращает.
Если второй параметр не указан, используется значение, возвращаемое функцией random()
:
>>> import random # Подключаем модуль random
>>> arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> random.shuffle(arr) # Перемешиваем список случайным образом
>>> arr
[2, 7, 10, 4, 6, 8, 9, 3, 1, 5]
8.10. Выбор элементов случайным образом
Получить элементы из списка случайным образом позволяют следующие функции из моду- ля random
:
 choice(<Последовательность>)
— возвращает случайный элемент из любой последова- тельности (строки, списка, кортежа):
>>> import random # Подключаем модуль random
>>> random.choice(["s", "t", "r"]) # Список 's'

158
Часть I. Основы языка Python
 sample(<Последовательность>, <Количество элементов>)
— возвращает список из ука- занного количества элементов. В этот список попадут элементы из последовательности, выбранные случайным образом. В качестве последовательности можно указать любые объекты, поддерживающие итерации:
>>> arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> random.sample(arr, 2)
[7, 10]
>>> arr # Сам список не изменяется
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
8.11. Сортировка списка
Отсортировать список позволяет метод sort()
. Он имеет следующий формат: sort([key=None][, reverse=False])
Все параметры не являются обязательными. Метод изменяет текущий список и ничего не возвращает. Отсортируем список по возрастанию с параметрами по умолчанию:
>>> arr = [2, 7, 10, 4, 6, 8, 9, 3, 1, 5]
>>> arr.sort() # Изменяет текущий список
>>> arr
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Чтобы отсортировать список по убыванию, следует в параметре reverse указать значение
True
:
>>> arr = [2, 7, 10, 4, 6, 8, 9, 3, 1, 5]
>>> arr.sort(reverse=True) # Сортировка по убыванию
>>> arr
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Надо заметить, что стандартная сортировка зависит от регистра символов (листинг 8.7).
Листинг 8.7. Стандартная сортировка arr = ["единица1", "Единый", "Единица2"] arr.sort() for i in arr: print(i, end=" ")
# Результат выполнения: Единица2 Единый единица1
В параметре key метода sort()
можно указать функцию, выполняющую какое-либо дейст- вие над каждым элементом списка. В качестве единственного параметра она должна при- нимать значение очередного элемента списка, а в качестве результата — возвращать результат действий над ним. Этот результат будет участвовать в процессе сортировки, но значения самих элементов списка не изменятся.
Выполнив пример из листинга 8.7, мы получили неправильный результат сортировки, ведь
Единый и
Единица2
больше единица1
. Чтобы регистр символов не учитывался, в параметре key мы укажем функцию для изменения регистра символов (листинг 8.8).

Глава 8. Списки, кортежи, множества и диапазоны
159
Листинг 8.8. Пользовательская сортировка arr = ["единица1", "Единый", "Единица2"] arr.sort(key=str.lower) # Указываем метод lower() for i in arr: print(i, end=" ")
# Результат выполнения: единица1 Единица2 Единый
Метод sort()
сортирует сам список и не возвращает никакого значения. В некоторых случаях необходимо получить отсортированный список, а текущий список оставить без изменений. Для этого следует воспользоваться функцией sorted()
. Функция имеет сле- дующий формат: sorted(<Последовательность>[, key=None][, reverse=False])
В первом параметре указывается список, который необходимо отсортировать. Остальные параметры эквивалентны параметрам метода sort()
. Вот пример использования функции sorted()
:
>>> arr = [2, 7, 10, 4, 6, 8, 9, 3, 1, 5]
>>> sorted(arr) # Возвращает новый список!
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> sorted(arr, reverse=True) # Возвращает новый список!
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> arr = ["единица1", "Единый", "Единица2"]
>>> sorted(arr, key=str.lower)
['единица1', 'Единица2', 'Единый']
8.12. Заполнение списка числами
Создать список, содержащий диапазон чисел, можно с помощью функции range()
. Она воз- вращает диапазон, который преобразуется в список вызовом функции list()
. Функция range()
имеет следующий формат: range([<Начало>, ]<Конец>[, <Шаг>])
Первый параметр задает начальное значение, а если он не указан, используется значение
0
Во втором параметре указывается конечное значение. Следует заметить, что это значение не входит в возвращаемый диапазон. Если параметр
<Шаг>
не указан, используется значение
1
. В качестве примера заполним список числами от
0
до
10
:
>>> list(range(11))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Создадим список, состоящий из диапазона чисел от
1
до
15
:
>>> list(range(1, 16))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Теперь изменим порядок следования чисел на противоположный:
>>> list(range(15, 0, -1))
[15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Если необходимо получить список со случайными числами (или случайными элементами из другого списка), то следует воспользоваться функцией sample(<Последовательность>,
<Количество элементов>)
из модуля random
:

160
Часть I. Основы языка Python
>>> import random
>>> arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> random.sample(arr, 3)
[1, 9, 5]
>>> random.sample(range(300), 5)
[259, 294, 142, 292, 245]
8.13. Преобразование списка в строку
Преобразовать список в строку позволяет метод join()
. Элементы добавляются в форми- руемую строку через указанный разделитель. Формат метода:
<Строка> = <Разделитель>.join(<Последовательность>)
Пример:
>>> arr = ["word1", "word2", "word3"]
>>> " — ".join(arr)
'word1 — word2 — word3'
Обратите внимание на то, что элементы списка должны быть строками, иначе возвращается исключение
TypeError
:
>>> arr = ["word1", "word2", "word3", 2]
>>> " — ".join(arr)
Traceback (most recent call last):
File "
", line 1, in
" — ".join(arr)
TypeError: sequence item 3: expected str instance, int found
Избежать этого исключения можно с помощью выражения-генератора, внутри которого текущий элемент списка преобразуется в строку с помощью функции str()
:
>>> arr = ["word1", "word2", "word3", 2]
>>> " — ".join( ( str(i) for i in arr ) )
'word1 — word2 — word3 — 2'
Кроме того, с помощью функции str()
можно сразу получить строковое представление списка:
>>> arr = ["word1", "word2", "word3", 2]
>>> str(arr)
"['word1', 'word2', 'word3', 2]"
8.14. Кортежи
Кортежи, как и списки, являются упорядоченными последовательностями элементов. Они во многом аналогичны спискам, но имеют одно очень важное отличие — изменить кортеж нельзя. Можно сказать, что кортеж — это список, доступный только для чтения.
Создать кортеж можно следующими способами:
 с помощью функции tuple([<Последовательность>])
. Функция позволяет преобразовать любую последовательность в кортеж. Если параметр не указан, создается пустой кортеж:

Глава 8. Списки, кортежи, множества и диапазоны
161
>>> tuple() # Создаем пустой кортеж
()
>>> tuple("String") # Преобразуем строку в кортеж
('S', 't', 'r', 'i', 'n', 'g')
>>> tuple([1, 2, 3, 4, 5]) # Преобразуем список в кортеж
(1, 2, 3, 4, 5)
 указав все элементы через запятую внутри круглых скобок (или без скобок):
>>> t1 = () # Создаем пустой кортеж
>>> t2 = (5,) # Создаем кортеж из одного элемента
>>> t3 = (1, "str", (3, 4)) # Кортеж из трех элементов
>>> t4 = 1, "str", (3, 4) # Кортеж из трех элементов
>>> t1, t2, t3, t4
((), (5,), (1, 'str', (3, 4)), (1, 'str', (3, 4)))
Обратите особое внимание на вторую строку примера. Чтобы создать кортеж из одного элемента, необходимо в конце указать запятую. Именно запятые формируют кортеж, а не круглые скобки. Если внутри круглых скобок нет запятых, будет создан объект дру- гого типа:
>>> t = (5); type(t) # Получили число, а не кортеж!

>>> t = ("str"); type(t) # Получили строку, а не кортеж!

Четвертая строка в исходном примере также доказывает, что не скобки формируют кор- теж, а запятые. Помните, что любое выражение в языке Python можно заключить в круг- лые скобки, а чтобы получить кортеж, необходимо указать запятые.
Позиция элемента в кортеже задается индексом. Обратите внимание на то, что нумерация элементов кортежа (как и списка) начинается с
0
, а не с
1
. Как и все последовательности, кортежи поддерживают обращение к элементу по индексу, получение среза, конкатенацию
(оператор
+
), повторение (оператор
*
), проверку на вхождение (оператор in
) и невхождение
(оператор not in
):
>>> t = (1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> t[0] # Получаем значение первого элемента кортежа
1
>>> t[::-1] # Изменяем порядок следования элементов
(9, 8, 7, 6, 5, 4, 3, 2, 1)
>>> t[2:5] # Получаем срез
(3, 4, 5)
>>> 8 in t, 0 in t # Проверка на вхождение
(True, False)
>>> (1, 2, 3) * 3 # Повторение
(1, 2, 3, 1, 2, 3, 1, 2, 3)
>>> (1, 2, 3) + (4, 5, 6) # Конкатенация
(1, 2, 3, 4, 5, 6)
Кортежи, как уже неоднократно отмечалось, относятся к неизменяемым типам данных.
Иными словами, можно получить элемент по индексу, но изменить его нельзя:
>>> t = (1, 2, 3) # Создаем кортеж
>>> t[0] # Получаем элемент по индексу
1

162
Часть I. Основы языка Python
>>> t[0] = 50 # Изменить элемент по индексу нельзя!
Traceback (most recent call last):
File "
", line 1, in t[0] = 50 # Изменить элемент по индексу нельзя!
TypeError: 'tuple' object does not support item assignment
Кортежи поддерживают уже знакомые нам по спискам функции len()
, min()
, max()
, методы index()
и count()
:
>>> t = (1, 2, 3) # Создаем кортеж
>>> len(t) # Получаем количество элементов
3
>>> t = (1, 2, 1, 2, 1)
>>> t.index(1), t.index(2) # Ищем элементы в кортеже
(0, 1)
8.15. Множества
Множество — это неупорядоченная последовательность уникальных элементов. Объявить множество можно с помощью функции set()
:
>>> s = set()
>>> s set([])
Функция set()
также позволяет преобразовать элементы последовательности во множество:
>>> set("string") # Преобразуем строку set(['g', 'i', 'n', 's', 'r', 't'])
>>> set([1, 2, 3, 4, 5]) # Преобразуем список set([1, 2, 3, 4, 5])
>>> set((1, 2, 3, 4, 5)) # Преобразуем кортеж set([1, 2, 3, 4, 5])
>>> set([1, 2, 3, 1, 2, 3]) # Остаются только уникальные элементы set([1, 2, 3])
Перебрать элементы множества позволяет цикл for
:
>>> for i in set([1, 2, 3]): print i
1 2 3
Получить количество элементов множества позволяет функция len()
:
>>> len(set([1, 2, 3]))
3
Для работы с множествами предназначены следующие операторы и соответствующие им методы:

|
и union()
— объединяют два множества:
>>> s = set([1, 2, 3])
>>> s.union(set([4, 5, 6])), s | set([4, 5, 6])
(set([1, 2, 3, 4, 5, 6]), set([1, 2, 3, 4, 5, 6]))
Если элемент уже содержится во множестве, то он повторно добавлен не будет:
>>> set([1, 2, 3]) | set([1, 2, 3]) set([1, 2, 3])

Глава 8. Списки, кортежи, множества и диапазоны
163
 a |= b и a.update(b)
— добавляют элементы множества b
во множество a
:
>>> s = set([1, 2, 3])
>>> s.update(set([4, 5, 6]))
>>> s set([1, 2, 3, 4, 5, 6])
>>> s |= set([7, 8, 9])
>>> s set([1, 2, 3, 4, 5, 6, 7, 8, 9])

- и difference()
— вычисляют разницу множеств:
>>> set([1, 2, 3]) - set([1, 2, 4]) set([3])
>>> s = set([1, 2, 3])
>>> s.difference(set([1, 2, 4])) set([3])
 a -= b и a.difference_update(b)
— удаляют элементы из множества a
, которые сущест- вуют и во множестве a
, и во множестве b
:
>>> s = set([1, 2, 3])
>>> s.difference_update(set([1, 2, 4]))
>>> s set([3])
>>> s -= set([3, 4, 5])
>>> s set([])

&
и intersection()
— пересечение множеств. Позволяют получить элементы, которые существуют в обоих множествах:
>>> set([1, 2, 3]) & set([1, 2, 4]) set([1, 2])
>>> s = set([1, 2, 3])
>>> s.intersection(set([1, 2, 4])) set([1, 2])
 a &= b и a.intersection_update(b)
— во множестве a
останутся элементы, которые су- ществуют и во множестве a
, и во множестве b
:
>>> s = set([1, 2, 3])
>>> s.intersection_update(set([1, 2, 4]))
>>> s set([1, 2])
>>> s &= set([1, 6, 7])
>>> s set([1])

^
и symmetric_difference()
— возвращают все элементы обоих множеств, исключая элементы, которые присутствуют в обоих этих множествах:
>>> s = set([1, 2, 3])
>>> s ^ set([1, 2, 4]), s.symmetric_difference(set([1, 2, 4]))
(set([3, 4]), set([3, 4]))
>>> s ^ set([1, 2, 3]), s.symmetric_difference(set([1, 2, 3]))
(set([]), set([]))

164
Часть I. Основы языка Python
>>> s ^ set([4, 5, 6]), s.symmetric_difference(set([4, 5, 6]))
(set([1, 2, 3, 4, 5, 6]), set([1, 2, 3, 4, 5, 6]))
 a ^= b и a.symmetric_difference_update(b)
— во множестве a
будут все элементы обо- их множеств, исключая те, что присутствуют в обоих этих множествах:
>>> s = set([1, 2, 3])
>>> s.symmetric_difference_update(set([1, 2, 4]))
>>> s set([3, 4])
>>> s ^= set([3, 5, 6])
>>> s set([4, 5, 6])
Операторы сравнения множеств:
 in
— проверка наличия элемента во множестве:
>>> s = set([1, 2, 3, 4, 5])
>>> 1 in s, 12 in s
(True, False)
 not in
— проверка отсутствия элемента во множестве:
>>> s = set([1, 2, 3, 4, 5])
>>> 1 in s, 12 in s
(False, True)

==
— проверка на равенство:
>>> set([1, 2, 3]) == set([1, 2, 3])
True
>>> set([1, 2, 3]) == set([3, 2, 1])
True
>>> set([1, 2, 3]) == set([1, 2, 3, 4])
False
 a <= b и a.issubset(b)
— проверяют, входят ли все элементы множества a
во множест- во b
:
>>> s = set([1, 2, 3])
>>> s <= set([1, 2]), s <= set([1, 2, 3, 4])
(False, True)
>>> s.issubset(set([1, 2])), s.issubset(set([1, 2, 3, 4]))
(False, True)
 a < b
— проверяет, входят ли все элементы множества a
во множество b
, причем мно- жество a
не должно быть равно множеству b
:
>>> s = set([1, 2, 3])
>>> s < set([1, 2, 3]), s < set([1, 2, 3, 4])
(False, True)
 a >= b и a.issuperset(b)
— проверяют, входят ли все элементы множества b
во множе- ство a
:
>>> s = set([1, 2, 3])
>>> s >= set([1, 2]), s >= set([1, 2, 3, 4])
(True, False)

Глава 8. Списки, кортежи, множества и диапазоны
165
>>> s.issuperset(set([1, 2])), s.issuperset(set([1, 2, 3, 4]))
(True, False)
 a > b
— проверяет, входят ли все элементы множества b
во множество a
, причем мно- жество a
не должно быть равно множеству b
:
>>> s = set([1, 2, 3])
>>> s > set([1, 2]), s > set([1, 2, 3])
(True, False)
 a.isdisjoint(b)
— проверяет, являются ли множества a
и b
полностью разными, т. е. не содержащими ни одного совпадающего элемента:
>>> s = set([1, 2, 3])
>>> s.isdisjoint(set([4, 5, 6]))
True
>>> s.isdisjoint(set([1, 3, 5]))
False
Для работы с множествами предназначены следующие методы:
 copy()
— создает копию множества. Обратите внимание на то, что оператор
=
присваи- вает лишь ссылку на тот же объект, а не копирует его:
>>> s = set([1, 2, 3])
>>> c = s; s is c # С помощью = копию создать нельзя!
True
>>> c = s.copy() # Создаем копию объекта
>>> c set([1, 2, 3])
>>> s is c # Теперь это разные объекты
False
 add(<Элемент>)
— добавляет
<Элемент>
во множество:
>>> s = set([1, 2, 3])
>>> s.add(4); s set([1, 2, 3, 4])
 remove(<Элемент>)
— удаляет
<Элемент>
из множества. Если элемент не найден, то воз- буждается исключение
KeyError
:
>>> s = set([1, 2, 3])
>>> s.remove(3); s # Элемент существует set([1, 2])
>>> s.remove(5) # Элемент НЕ существует
Traceback (most recent call last):
File "
", line 1, in s.remove(5) # Элемент НЕ существует
KeyError: 5
 discard(<Элемент>)
— удаляет
<Элемент>
из множества, если он присутствует. Если ука- занный элемент не существует, никакого исключения не возбуждается:
>>> s = set([1, 2, 3])
>>> s.discard(3); s # Элемент существует set([1, 2])

166
Часть I. Основы языка Python
>>> s.discard(5); s # Элемент НЕ существует set([1, 2])
 pop()
— удаляет произвольный элемент из множества и возвращает его. Если элементов нет, возбуждается исключение
KeyError
:
>>> s = set([1, 2])
>>> s.pop(), s
(1, set([2]))
>>> s.pop(), s
(2, set([]))
>>> s.pop() # Если нет элементов, то будет ошибка
Traceback (most recent call last):
File "
", line 1, in s.pop() # Если нет элементов, то будет ошибка
KeyError: 'pop from an empty set'
 clear()
— удаляет все элементы из множества:
>>> s = set([1, 2, 3])
>>> s.clear(); s set([])
Помимо генераторов списков и генераторов словарей, язык Python 3 поддерживает генера- торы множеств. Их синтаксис похож на синтаксис генераторов списков, но выражение заключается в фигурные скобки, а не в квадратные. Так как результатом является множест- во, все повторяющиеся элементы будут удалены:
>>> {x for x in [1, 2, 1, 2, 1, 2, 3]}
{1, 2, 3}
Генераторы множеств могут иметь сложную структуру. Например, состоять из нескольких вложенных циклов for и (или) содержать оператор ветвления if после цикла. Создадим из элементов исходного списка множество, содержащее только уникальные элементы с чет- ными значениями:
>>> {x for x in [1, 2, 1, 2, 1, 2, 3] if x % 2 == 0}
{2}
Язык Python поддерживает еще один тип множеств — frozenset
. В отличие от типа set
, множество типа frozenset нельзя изменить. Объявить такое множество можно с помощью функции frozenset()
:
>>> f = frozenset()
>>> f frozenset([])
Функция frozenset()
позволяет также преобразовать элементы последовательности во множество:
>>> frozenset("string") # Преобразуем строку frozenset(['g', 'i', 'n', 's', 'r', 't'])
>>> frozenset([1, 2, 3, 4, 4]) # Преобразуем список frozenset([1, 2, 3, 4])
>>> frozenset((1, 2, 3, 4, 4)) # Преобразуем кортеж frozenset([1, 2, 3, 4])

Глава 8. Списки, кортежи, множества и диапазоны
167
Множества frozenset поддерживают операторы, которые не изменяют само множество, а также следующие методы: copy()
, difference()
, intersection()
, issubset()
, issuperset()
, symmetric_difference()
и union()
8.16. Диапазоны
Диапазоны, как следует из самого их названия, — это последовательности целых чисел с заданными начальным и конечным значениями и шагом (промежутком между соседними числами). Как и списки, кортежи и множества, диапазоны представляют собой последова- тельности и, подобно кортежам, являются неизменяемыми.
Важнейшим преимуществом диапазонов перед другими видами последовательностей явля- ется их компактность — вне зависимости от количества входящих в него элементов-чисел, диапазон всегда занимает один и тот же объем оперативной памяти. Однако в диапазон могут входить лишь числа, последовательно стоящие друг за другом, — сформировать диа- пазон на основе произвольного набора чисел или данных другого типа, даже чисел с пла- вающей точкой, невозможно.
Диапазоны чаще всего используются для проверки вхождения значения в какой-либо ин- тервал и для организации циклов.
Для создания диапазона применяется функция range()
: range([<Начало>, ]<Конец>[, <Шаг>])
Первый параметр задает начальное значение — если он не указан, используется значение
0
Во втором параметре указывается конечное значение. Следует заметить, что это значение не входит в возвращаемый диапазон. Если параметр
<Шаг>
не указан, используется значение
1
:
>>> r = range(1, 10)
>>> for i in r: print(i, end = " ")
1 2 3 4 5 6 7 8 9
>>> r = range(10, 110, 10)
>>> for i in r: print(i, end = " ")
10 20 30 40 50 60 70 80 90 100
>>> r = range(10, 1, -1)
>>> for i in r: print(i, end = " ")
10 9 8 7 6 5 4 3 2
Преобразовать диапазон в список, кортеж, обычное или неизменяемое множество можно с помощью функций list()
, tuple()
, set()
или frozenset()
соответственно:
>>> list(range(1, 10)) # Преобразуем в список
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> tuple(range(1, 10)) # Преобразуем в кортеж
(1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> set(range(1, 10)) # Преобразуем в множество
{1, 2, 3, 4, 5, 6, 7, 8, 9}
Множества поддерживают доступ к элементу по индексу, получение среза (в результате возвращается также диапазон), проверку на вхождение и невхождение, функции len()
, min()
, max()
, методы index()
и count()
:
>>> r = range(1, 10)
>>> r[2], r[-1]
(3, 9)

168
Часть I. Основы языка Python
>>> r[2:4] range(3, 5)
>>> 2 in r, 12 in r
(True, False)
>>> 3 not in r, 13 not in r
(False, True)
>>> len(r), min(r), max(r)
(9, 1, 9)
>>> r.index(4), r.count(4)
(3, 1)
Поддерживается ряд операторов, позволяющих сравнить два диапазона:

==
— возвращает
True
, если диапазоны равны, и
False
— в противном случае. Диапазо- ны считаются равными, если они содержат одинаковые последовательности чисел:
>>> range(1, 10) == range(1, 10, 1)
True
>>> range(1, 10, 2) == range(1, 11, 2)
True
>>> range(1, 10, 2) == range(1, 12, 2)
False

!=
— возвращает
True
, если диапазоны не равны, и
False
— в противном случае:
>>> range(1, 10, 2) != range(1, 12, 2)
True
>>> range(1, 10) != range(1, 10, 1)
False
Также диапазоны поддерживают атрибуты start
, stop и step
, возвращающие, соответст- венно, начальную, конечную границы диапазона и его шаг:
>>> r = range(1, 10)
>>> r.start, r.stop, r.step
(1, 10, 1)
8.17. Модуль itertools
Модуль itertools содержит функции, позволяющие генерировать различные последова- тельности на основе других последовательностей, производить фильтрацию элементов и др.
Все функции возвращают объекты, поддерживающие итерации. Прежде чем использовать функции, необходимо подключить модуль с помощью инструкции: import itertools
8.17.1. Генерирование неопределенного количества значений
Для генерации неопределенного количества значений предназначены следующие функции:
 count([start=0][, step=1])
— создает бесконечно нарастающую последовательность значений. Начальное значение задается параметром start
, а шаг — параметром step
:
>>> import itertools
>>> for i in itertools.count():

Глава 8. Списки, кортежи, множества и диапазоны
169 if i > 10: break print(i, end=" ")
0 1 2 3 4 5 6 7 8 9 10
>>> list(zip(itertools.count(), "абвгд"))
[(0, 'а'), (1, 'б'), (2, 'в'), (3, 'г'), (4, 'д')]
>>> list(zip(itertools.count(start=2, step=2), "абвгд"))
[(2, 'а'), (4, 'б'), (6, 'в'), (8, 'г'), (10, 'д')]
 cycle(<Последовательность>)
— на каждой итерации возвращает очередной элемент последовательности. Когда будет достигнут конец последовательности, перебор начнет- ся сначала, и так до бесконечности:
>>> n = 1
>>> for i in itertools.cycle("абв"): if n > 10: break print(i, end=" ") n += 1 а б в а б в а б в а
>>> list(zip(itertools.cycle([0, 1]), "абвгд"))
[(0, 'а'), (1, 'б'), (0, 'в'), (1, 'г'), (0, 'д')]
 repeat(<Объект>[, <Количество повторов>])
— возвращает объект указанное количест- во раз. Если количество повторов не указано, объект возвращается бесконечно:
>>> list(itertools.repeat(1, 10))
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
>>> list(zip(itertools.repeat(5), "абвгд"))
[(5, 'а'), (5, 'б'), (5, 'в'), (5, 'г'), (5, 'д')]
8.17.2. Генерирование комбинаций значений
Получить различные комбинации значений позволяют следующие функции:
 combinations()
— на каждой итерации возвращает кортеж, содержащий комбинацию из указанного количества элементов. При этом элементы в кортеже гарантированно будут разными. Формат функции: combinations(<Последовательность>, <Количество элементов>)
Примеры:
>>> import itertools
>>> list(itertools.combinations('абвг', 2))
[('а', 'б'), ('а', 'в'), ('а', 'г'), ('б', 'в'), ('б', 'г'),
('в', 'г')]
>>> ["".join(i) for i in itertools.combinations('абвг', 2)]
['аб', 'ав', 'аг', 'бв', 'бг', 'вг']
>>> list(itertools.combinations('вгаб', 2))
[('в', 'г'), ('в', 'а'), ('в', 'б'), ('г', 'а'), ('г', 'б'),
('а', 'б')]
>>> list(itertools.combinations('абвг', 3))
[('а', 'б', 'в'), ('а', 'б', 'г'), ('а', 'в', 'г'),
('б', 'в', 'г')]

170
Часть I. Основы языка Python
 combinations_with_replacement()
— на каждой итерации возвращает кортеж, содержа- щий комбинацию из указанного количества элементов. При этом кортеж может содер- жать одинаковые элементы. Формат функции: combinations_with_replacement(<Последовательность>,
<Количество элементов>)
Примеры:
>>> list(itertools.combinations_with_replacement('абвг', 2))
[('а', 'а'), ('а', 'б'), ('а', 'в'), ('а', 'г'), ('б', 'б'),
('б', 'в'), ('б', 'г'), ('в', 'в'), ('в', 'г'), ('г', 'г')]
>>> list(itertools.combinations_with_replacement('вгаб', 2))
[('в', 'в'), ('в', 'г'), ('в', 'а'), ('в', 'б'), ('г', 'г'),
('г', 'а'), ('г', 'б'), ('а', 'а'), ('а', 'б'), ('б', 'б')]
 permutations()
— на каждой итерации возвращает кортеж, содержащий комбинацию из указанного количества элементов. Если количество элементов не указано, то использу- ется длина последовательности. Формат функции: permutations(<Последовательность>[, <Количество элементов>])
Примеры:
>>> list(itertools.permutations('абвг', 2))
[('а', 'б'), ('а', 'в'), ('а', 'г'), ('б', 'а'), ('б', 'в'),
('б', 'г'), ('в', 'а'), ('в', 'б'), ('в', 'г'), ('г', 'а'),
('г', 'б'), ('г', 'в')]
>>> ["".join(i) for i in itertools.permutations('абвг')]
['абвг', 'абгв', 'авбг', 'авгб', 'агбв', 'агвб', 'бавг',
'багв', 'бваг', 'бвга', 'бгав', 'бгва', 'вабг', 'вагб',
'вбаг', 'вбга', 'вгаб', 'вгба', 'габв', 'гавб', 'гбав',
'гбва', 'гваб', 'гвба']
 product()
— на каждой итерации возвращает кортеж, содержащий комбинацию из эле- ментов одной или нескольких последовательностей. Формат функции: product(<Последовательность1>[,..., <ПоследовательностьN>][, repeat=1])
Примеры:
>>> from itertools import product
>>> list(product('абвг', repeat=2))
[('а', 'а'), ('а', 'б'), ('а', 'в'), ('а', 'г'), ('б', 'а'),
('б', 'б'), ('б', 'в'), ('б', 'г'), ('в', 'а'), ('в', 'б'),
('в', 'в'), ('в', 'г'), ('г', 'а'), ('г', 'б'), ('г', 'в'),
('г', 'г')]
>>> ["".join(i) for i in product('аб', 'вг', repeat=1)]
['ав', 'аг', 'бв', 'бг']
>>> ["".join(i) for i in product('аб', 'вг', repeat=2)]
['авав', 'аваг', 'авбв', 'авбг', 'агав', 'агаг', 'агбв',
'агбг', 'бвав', 'бваг', 'бвбв', 'бвбг', 'бгав', 'бгаг',
'бгбв', 'бгбг']

Глава 8. Списки, кортежи, множества и диапазоны
171 8.17.3. Фильтрация элементов последовательности
Для фильтрации элементов последовательности предназначены следующие функции:
 filterfalse(<Функция>, <Последовательность>
) — возвращает элементы последователь- ности (по одному на каждой итерации), для которых функция, указанная в первом пара- метре, вернет значение
False
:
>>> import itertools
>>> def func(x): return x > 3
>>> list(itertools.filterfalse(func, [4, 5, 6, 0, 7, 2, 3]))
[0, 2, 3]
>>> list(filter(func, [4, 5, 6, 0, 7, 2, 3]))
[4, 5, 6, 7]
Если в первом параметре вместо названия функции указать значение
None
, то каждый элемент последовательности будет проверен на соответствие значению
False
. Если эле- мент в логическом контексте возвращает значение
True
, то он не войдет в возвращаемый результат:
>>> list(itertools.filterfalse(None, [0, 5, 6, 0, 7, 0, 3]))
[0, 0, 0]
>>> list(filter(None, [0, 5, 6, 0, 7, 0, 3]))
[5, 6, 7, 3]
 dropwhile(<Функция>, <Последовательность>)
— возвращает элементы последователь- ности (по одному на каждой итерации), начиная с элемента, для которого функция, ука- занная в первом параметре, вернет значение
False
:
>>> def func(x): return x > 3
>>> list(itertools.dropwhile(func, [4, 5, 6, 0, 7, 2, 3]))
[0, 7, 2, 3]
>>> list(itertools.dropwhile(func, [4, 5, 6, 7, 8]))
[]
>>> list(itertools.dropwhile(func, [1, 2, 4, 5, 6, 7, 8]))
[1, 2, 4, 5, 6, 7, 8]
 takewhile(<Функция>, <Последовательность>)
— возвращает элементы последователь- ности (по одному на каждой итерации), пока не встретится элемент, для которого функ- ция, указанная в первом параметре, вернет значение
False
:
>>> def func(x): return x > 3
>>> list(itertools.takewhile(func, [4, 5, 6, 0, 7, 2, 3]))
[4, 5, 6]
>>> list(itertools.takewhile(func, [4, 5, 6, 7, 8]))
[4, 5, 6, 7, 8]
>>> list(itertools.takewhile(func, [1, 2, 4, 5, 6, 7, 8]))
[]
 compress()
— производит фильтрацию последовательности, указанной в первом пара- метре. Элемент возвращается, только если соответствующий элемент (с таким же индек- сом) из второй последовательности трактуется как истина. Сравнение заканчивается, когда достигнут конец одной из последовательностей. Формат функции:

172
Часть I. Основы языка Python compress(<Фильтруемая последовательность>,
<Последовательность логических значений>)
Примеры:
>>> list(itertools.compress('абвгде', [1, 0, 0, 0, 1, 1]))
['а', 'д', 'е']
>>> list(itertools.compress('абвгде', [True, False, True]))
['а', 'в']
8.17.4. Прочие функции
Помимо функций, которые мы рассмотрели в предыдущих подразделах, модуль itertools содержит несколько дополнительных функций:
 islice()
— на каждой итерации возвращает очередной элемент последовательности.
Поддерживаются форматы: islice(<Последовательность>, <Конечная граница>) и islice(<Последовательность>, <Начальная граница>, <Конечная граница>[, <Шаг>])
Если
<Шаг>
не указан, будет использовано значение
1
Примеры:
>>> list(itertools.islice("абвгдезж", 3))
['а', 'б', 'в']
>>> list(itertools.islice("абвгдезж", 3, 6))
['г', 'д', 'е']
>>> list(itertools.islice("абвгдезж", 3, 6, 2))
['г', 'е']
 starmap(<Функция>, <Последовательность>)
— формирует последовательность на осно- вании значений, возвращенных указанной функцией. Исходная последовательность должна содержать в качестве элементов кортежи — именно над элементами этих корте- жей функция и станет вычислять значения, которые войдут в генерируемую последова- тельность. Примеры суммирования значений:
>>> import itertools
>>> def func1(x, y): return x + y
>>> list(itertools.starmap(func1, [(1, 2), (4, 5), (6, 7)]))
[3, 9, 13]
>>> def func2(x, y, z): return x + y + z
>>> list(itertools.starmap(func2, [(1, 2, 3), (4, 5, 6)]))
[6, 15]
 zip_longest()
— на каждой итерации возвращает кортеж, содержащий элементы после- довательностей, которые расположены на одинаковом смещении. Если последователь- ности имеют разное количество элементов, вместо отсутствующего элемента вставляет- ся объект, указанный в параметре fillvalue
. Формат функции: zip_longest(<Последовательность1>[, ..., <ПоследовательностьN>]
[, fillvalue=None])

Глава 8. Списки, кортежи, множества и диапазоны
173
Примеры:
>>> list(itertools.zip_longest([1, 2, 3], [4, 5, 6]))
[(1, 4), (2, 5), (3, 6)]
>>> list(itertools.zip_longest([1, 2, 3], [4]))
[(1, 4), (2, None), (3, None)]
>>> list(itertools.zip_longest([1, 2, 3], [4], fillvalue=0))
[(1, 4), (2, 0), (3, 0)]
>>> list(zip([1, 2, 3], [4]))
[(1, 4)]
 accumulate(<Последовательность>[, <функция>])
— на каждой итерации возвращает результат, полученный выполнением определенного действия над текущим элементом и результатом, полученным на предыдущей итерации. Выполняемая операция задается параметром
<Функция>
, а если он не указан, выполняется операция сложения. Функция, выполняющая операцию, должна принимать два параметра и возвращать результат. На первой итерации всегда возвращается первый элемент переданной последовательности:
>>> # Выполняем сложение
>>> list(itertools.accumulate([1, 2, 3, 4, 5, 6]))
[1, 3, 6, 10, 15, 21]
>>> # [1, 1+2, 3+3, 6+4, 10+5, 15+6]
>>> # Выполняем умножение
>>> def func(x, y): return x * y
>>> list(itertools.accumulate([1, 2, 3, 4, 5, 6], func))
[1, 2, 6, 24, 120, 720]
>>> # [1, 1*2, 2*3, 6*4, 24*5, 120*6]
 chain()
— на каждой итерации возвращает элементы сначала из первой последователь- ности, затем из второй и т. д. Формат функции: chain(<Последовательность1>[, ..., <ПоследовательностьN>])
Примеры:
>>> arr1, arr2, arr3 = [1, 2, 3], [4, 5], [6, 7, 8, 9]
>>> list(itertools.chain(arr1, arr2, arr3))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(itertools.chain("abc", "defg", "hij"))
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
>>> list(itertools.chain("abc", ["defg", "hij"]))
['a', 'b', 'c', 'defg', 'hij']
 chain.from_iterable(<Последовательность>)
— аналогична функции chain()
, но прини- мает одну последовательность, каждый элемент которой считается отдельной последо- вательностью:
>>> list(itertools.chain.from_iterable(["abc", "defg", "hij"]))
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
 tee(<Последовательность>[, <Количество>])
— возвращает кортеж, содержащий не- сколько одинаковых итераторов для последовательности. Если второй параметр не ука- зан, то возвращается кортеж из двух итераторов:

174
Часть I. Основы языка Python
>>> arr = [1, 2, 3]
>>> itertools.tee(arr)
(
1   ...   11   12   13   14   15   16   17   18   ...   83


написать администратору сайта