</>
Topic 12 of 18

Course materials are currently available in Russian only.

Кортежи и множества

selfedu · The video is optional — everything you need is in the text below.Open on YouTube ↗

Список — универсальная коллекция. Но есть ещё два типа, которые делают некоторые задачи проще и быстрее: кортежи и множества.

Кортежи

Кортеж (tuple) похож на список, но его нельзя изменить. Записывается в круглых скобках:

point = (3, 5)
print(point[0])     # 3
point[0] = 10       # ошибка: кортеж неизменяем

Кортежи удобны, чтобы хранить несколько связанных значений вместе: координаты, «имя и возраст», «день и температура».

Распаковка

Кортеж можно разложить по переменным — мы уже делали это при вводе:

x, y = (3, 5)
name, age = "Лена", 14       # скобки можно не писать

Отсюда удобный приём — обмен значений без третьей переменной:

a, b = 1, 2
a, b = b, a       # теперь a = 2, b = 1

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

cities = [("Казань", 1300), ("Тверь", 400), ("Пермь", 1000)]
for name, population in cities:
    print(name, population)

Сравнение и сортировка кортежей

Кортежи сравниваются поэлементно: сначала первые элементы, при равенстве — вторые и так далее.

print((1, 9) < (2, 0))     # True — решает первый элемент
print((2, "б") < (2, "в")) # True — первые равны, решает второй

Поэтому список кортежей сортируется сразу по нескольким признакам:

fruits = [(3, "груша"), (1, "яблоко"), (3, "банан")]
fruits.sort()
print(fruits)   # [(1, 'яблоко'), (3, 'банан'), (3, 'груша')]

Сначала по числу, а при равных числах — по названию. Чтобы по одному признаку сортировать по убыванию, а по другому по возрастанию, можно хранить число с минусом: (-число, название). Так меньшее «минус число» соответствует большему числу.

Множества

Множество (set) хранит значения без повторов и без порядка:

colors = {"красный", "синий", "красный"}
print(len(colors))        # 2
empty = set()             # пустое множество (не {} — это словарь)

Добавление и проверка:

seen = set()
seen.add(5)
seen.add(5)               # повтор не добавится
print(5 in seen)          # True
seen.discard(5)           # удалить, если есть

Почему множества быстрые

Проверка x in список перебирает элементы по одному: для списка из 105 элементов это 105 сравнений. Проверка x in множество занимает одну операцию независимо от размера. Если в цикле много раз спрашиваешь «было ли уже такое значение?», храни увиденное во множестве.

nums = [4, 7, 4, 1, 7, 7]
seen = set()
first_repeat = None
for x in nums:
    if x in seen:
        first_repeat = x
        break
    seen.add(x)
print(first_repeat)       # 4

Операции над множествами

a = {1, 2, 3, 4}
b = {3, 4, 5}
print(a | b)   # {1, 2, 3, 4, 5} — объединение
print(a & b)   # {3, 4}          — пересечение
print(a - b)   # {1, 2}          — разность
print(a ^ b)   # {1, 2, 5}       — есть ровно в одном

Множество из списка: set(список). Так быстро убирают повторы: len(set(a)) — сколько разных значений в списке.

Порядок не гарантирован

У множества нет порядка элементов: печать print(s) может выдать их в неожиданной последовательности. Если в задаче нужен порядок, сделай sorted(s).

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

Итог

  • кортеж (a, b) — неизменяемый набор значений; распаковка x, y = t, обмен a, b = b, a;
  • кортежи сравниваются поэлементно — сортировка списка кортежей учитывает несколько признаков;
  • множество хранит значения без повторов, x in s работает за одну операцию;
  • | & - ^ — объединение, пересечение, разность, симметрическая разность;
  • у множества нет порядка — для вывода сортируй.