ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 05.12.2023
Просмотров: 852
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
Глава 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
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
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
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():