Кортежи в логическом контексте

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

>>> def is_it_true(anything):
... if anything:
... print("да, это истина")
... else:
... print("нет, это ложь")
...
>>> is_it_true(()) ①
нет, это ложь
>>> is_it_true(('a', 'b')) ②
да, это истина
>>> is_it_true((False,)) ③
да, это истина
>>> type((False)) ④
<class 'bool'>
>>> type((False,))
<class 'tuple'>

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

Присваивание нескольких значений за раз

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

>>> v = ('a', 2, True)
>>> (x, y, z) = v ①
>>> x
'a'
>>> y
2
>>> z
True

v — это кортеж из трех элементов, а (x, y, z) — кортеж из трёх переменных. Присвоение одного другому приводит к присвоению каждого значения из v каждой переменной в указанном порядке.

Это не единственный способ использования. Предположим, что вы хотите присвоить имена диапазону значений. Вы можете использовать встроенную функцию range() для быстрого присвоения сразу нескольких последовательных значений.

>>> (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7) ①
>>> MONDAY ②
0
>>> TUESDAY
1
>>> SUNDAY
6

Встроенная функция range() создаёт последовательность целых чисел. (Строго говоря, функция range() возвращает итератор, а не список или кортеж, но вы узнаете разницу чуть позже.) MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, и SUNDAY — определяемые переменные. (Этот пример заимствован из модуля calendar, небольшого забавного модуля, который отображает календари, примерно как программа cal из UNIX. В этом модуле определяются константы целого типа для дней недели.)
Теперь каждой переменной присвоено конкретное значение: MONDAY — это 0, TUESDAY — 1, и так далее.

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

Множества

Множество — это «мешок», содержащий неупорядоченные уникальные значения. Одно множество может содержать значения любых типов. Если у вас есть два множества, вы можете совершать над ними любые стандартные операции, например, объединение, пересечение и разность.

Создание множества

Начнём с самого начала. Создать множество очень легко.

>>> a_set = {1} ①
>>> a_set
{1}
>>> type(a_set) ②
<class 'set'>
>>> a_set = {1, 2} ③
>>> a_set
{1, 2}

Чтобы создать множество с одним значением, поместите его в фигурные скобки ({}).
Множества, вообще-то, реализуются как классы, но пока не беспокойтесь об этом.
Чтобы создать множество с несколькими значениями, отделите их друг от друга запятыми и поместите внутрь фигурных скобок.

Также вы можете создать множество из списка.

>>> a_list = ['a', 'b', 'mpilgrim', True, False, 42]
>>> a_set = set(a_list) ①
>>> a_set ②
{'a', False, 'b', True, 'mpilgrim', 42}
>>> a_list ③
['a', 'b', 'mpilgrim', True, False, 42]

Чтобы создать множество из списка, воспользуйтесь функцией set(). (Педанты, которые знают как реализованы множества, отметят, что на самом деле это создание экземпляра класса, а не вызов функции. Я обещаю, вы узнаете в чём разница далее в этой книге. Сейчас просто знайте, что set() ведет себя как функция и возвращает множество.)
Как я упоминал ранее, множество может содержать значения любых типов. И, как я упоминал ранее, множества неупорядочены. Это множество не помнит первоначальный порядок списка, из которого оно было создано. Если вы добавляете элементы в множество, оно не запоминает, в каком порядке они добавлялись.
Исходный список не изменился.

У вас ещё нет значений? Нет проблем. Можно создать пустое множество.

>>> a_set = set() ①
>>> a_set ②
set()
>>> type(a_set) ③
<class 'set'>
>>> len(a_set) ④
0
>>> not_sure = {} ⑤
>>> type(not_sure)
<class 'dict'>

Чтобы создать пустое множество, вызовите set() без аргументов.
Напечатанное представление пустого множества выглядит немного странно. Вы, наверное, ожидали увидеть {}? Это означало бы пустой словарь, а не пустое множество. О словарях вы узнаете далее в этой главе.
Несмотря на странное печатное представление, это действительно множество...
...и это множество не содержит ни одного элемента.
В силу исторических причуд, пришедших из Python 2, нельзя создать пустое множество с помощью двух фигурных скобок. На самом деле, они создают пустой словарь, а не множество.

Изменение множества

Есть два способа добавить элементы в существующее множество: метод add() и метод update().

>>> a_set = {1, 2}
>>> a_set.add(4) ①
>>> a_set
{1, 2, 4}
>>> len(a_set) ②
3
>>> a_set.add(1) ③
>>> a_set
{1, 2, 4}
>>> len(a_set) ④
3

Метод add() принимает один аргумент, который может быть любого типа, и добавляет данное значение в множество.
Теперь множество содержит 3 элемента.
Множества — мешки уникальных значений. Если попытаться добавить значение, которое уже присутствует в множестве, ничего не произойдет. Это не приведет в возникновению ошибки; просто нулевое действие.
Это множество все ещё состоит из 3 элементов.

>>> a_set = {1, 2, 3}
>>> a_set
{1, 2, 3}
>>> a_set.update({2, 4, 6}) ①
>>> a_set ②
{1, 2, 3, 4, 6}
>>> a_set.update({3, 6, 9}, {1, 2, 3, 5, 8, 13}) ③
>>> a_set
{1, 2, 3, 4, 5, 6, 8, 9, 13}
>>> a_set.update([10, 20, 30]) ④
>>> a_set
{1, 2, 3, 4, 5, 6, 8, 9, 10, 13, 20, 30}