Перейти к содержанию
Educora
Средний14 мин7 / 42

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

Научись использовать кортежи для неизменяемых данных, а множества — для наборов без повторов.

Проверь себя
В этом уроке ты узнаешь
  • Создавать кортеж и распаковывать его
  • Объяснять разницу между списком, кортежем и множеством
  • Удалять повторы с помощью множеств и выполнять объединение, пересечение и разность

Некоторые данные никогда не должны меняться: дни недели, географические координаты Баку, RGB-код цвета. А иногда нужны только неповторяющиеся значения: например, ты хочешь узнать, из каких городов заходят на сайт, но считать каждый город один раз. Для этих двух задач в Python есть особые типы — кортеж и множество.

Кортежи

Определение
Кортеж (tuple)

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

Python
baku = (40.41, 49.87)
print(baku)
print(baku[0])
print(len(baku))

days = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
print(days[-1], days.index('Wed'))
▸ Ожидаемый результат
(40.41, 49.87)
40.41
2
Sun 2

Индексы, срезы, len(), in и цикл for работают и с кортежами. Но если написать days[0] = 'Monday', Python выдаст ошибку TypeError: 'tuple' object does not support item assignment. На самом деле это преимущество: ни одна часть программы не сможет случайно изменить важные данные.

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

Python
lat, lon = (40.41, 49.87)
print('Latitude:', lat)
print('Longitude:', lon)

a = 5
b = 8
a, b = b, a
print(a, b)
▸ Ожидаемый результат
Latitude: 40.41
Longitude: 49.87
8 5

Распаковка работает и в циклах. Функция enumerate() выдаёт каждый элемент вместе с его номером в виде кортежа (номер, элемент) — это самый удобный способ пронумеровать список. start=1 заставляет счёт начинаться с 1.

Python
students = ['Aysel', 'Murad', 'Leyla']
for number, name in enumerate(students, start=1):
    print(f'{number}. {name}')

print(list(enumerate('ab')))
▸ Ожидаемый результат
1. Aysel
2. Murad
3. Leyla
[(0, 'a'), (1, 'b')]

Множества

Определение
Множество (set)

Набор неповторяющихся элементов в фигурных скобках {}. У элементов множества нет порядка, поэтому индексы использовать нельзя.

Множество автоматически отбрасывает повторы. Если передать список в функцию set(), от каждого значения останется только одно. Так как у множества нет порядка, для аккуратного вывода мы сортируем его с помощью sorted().

Python
print({3, 1, 2, 3, 1})

visitors = ['Baku', 'Ganja', 'Baku', 'Shaki', 'Ganja', 'Baku']
unique = set(visitors)
print(len(visitors), len(unique))
print(sorted(unique))

unique.add('Quba')
unique.add('Baku')
print(len(unique))
print('Shaki' in unique)
▸ Ожидаемый результат
{1, 2, 3}
6 3
['Baku', 'Ganja', 'Shaki']
4
True

Обрати внимание: повторное добавление 'Baku' ничего не изменило, ведь он уже был во множестве, — элементов стало 4, а не 5. Проверка через in во множествах работает намного быстрее, чем в списках.

Пример: уникальные слова

Сколько слов в предложении «the sun and the moon and the stars» и сколько из них уникальных?

Показать решение
split() разбивает предложение на список из 8 слов.
set() убирает повторы, остаются the, sun, and, moon, stars.
Ответ: 8 слов, из них 5 уникальных.
Python
text = 'the sun and the moon and the stars'
words = text.split()
print(len(words), 'words,', len(set(words)), 'unique')
▸ Ожидаемый результат
8 words, 5 unique

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

Знакомые по математике операции над множествами записываются в Python одним символом. Допустим, в школе есть шахматный кружок и кружок робототехники. Какие ученики ходят в оба?

ОперацияЗаписьРезультат
Объединениеa | bвсе элементы из a или b
Пересечениеa & bэлементы, которые есть и в a, и в b
Разностьa - bэлементы из a, которых нет в b
Симметрическая разностьa ^ bэлементы, которые есть только в одном из них
Python
chess = {'Aysel', 'Murad', 'Elvin'}
robotics = {'Murad', 'Leyla', 'Elvin', 'Nigar'}

print(sorted(chess & robotics))
print(sorted(chess | robotics))
print(sorted(chess - robotics))
print(sorted(chess ^ robotics))
▸ Ожидаемый результат
['Elvin', 'Murad']
['Aysel', 'Elvin', 'Leyla', 'Murad', 'Nigar']
['Aysel']
['Aysel', 'Leyla', 'Nigar']

Что выбрать?

СвойствоСписокКортежМножество
Запись[1, 2](1, 2){1, 2}
Можно менять?данетда
Есть порядок?даданет
Повторы допустимы?даданет
Когда использоватьизменяемый набор элементовнеизменные данныеуникальные элементы, быстрая проверка
Задание

Каждый элемент списка results — кортеж из имени и балла, например ('Aysel', 91). С помощью enumerate() и распаковки кортежа выведи результаты с номерами от 1, в виде 1. Aysel - 91.

Задание · Python
results = [('Aysel', 91), ('Murad', 78), ('Leyla', 85)]
# print: 1. Aysel - 91, then 2. Murad - 78, ...
▸ Ожидаемый результат
1. Aysel - 91
2. Murad - 78
3. Leyla - 85
Задание

Даны списки учеников, пришедших в кружок в понедельник и во вторник (имена могут повторяться). С помощью множеств выведи три строки: 1) сколько разных учеников пришло в понедельник, 2) список тех, кто пришёл в оба дня, по алфавиту, 3) сколько всего разных учеников пришло.

Задание · Python
monday = ['Aysel', 'Murad', 'Leyla', 'Aysel', 'Elvin']
tuesday = ['Leyla', 'Nigar', 'Murad', 'Nigar']
# 1) number of different pupils on Monday
# 2) sorted list of pupils who came on both days
# 3) number of different pupils in total
▸ Ожидаемый результат
4
['Leyla', 'Murad']
5

Главное

  • Кортеж — упорядоченный неизменяемый набор в ().
  • Распаковка присваивает значения нескольким переменным в одной строке: lat, lon = point.
  • Множество — неупорядоченные уникальные элементы в {}; set(list) убирает повторы.
  • | — объединение, & — пересечение, - — разность, ^ — симметрическая разность.
  • Пустое множество создаётся через set(), а {} — это пустой словарь.

Проверь себя

Вопросов: 10. Каждый правильный ответ приносит XP.

1 / 10
В чём главное отличие кортежа от списка?