Как найти пересечения множества python

In this article, a List of sets is given our task is to write a program to perform their intersection using Python.

Examples of finding the intersection of multiple sets

Input : test_list = [{5, 3, 6, 7}, {1, 3, 5, 2}, {7, 3, 8, 5}, {8, 4, 5, 3}]
Output : {3, 5}
Explanation : 3 and 5 is present in all the sets.

Method 1: Using a Logical operator

This is the simplest method to get the intersection of multiple sets using the Python logical operator

Python3

set_1 = {21, 10, 5, 11, 12}

set_2 = {5, 21, 3, 8, 9}

set_3 = {1, 21, 5, 3, 4, 5}

set4 = set1 & set2 & set3

print(set4)

Output:

{21, 5}

Method 2: Using intersection() + * operator

In this, we will perform tasks to get intersections using intersection() and the * operator is used to pack all the sets together.

Python3

test_list = [{5, 3, 6, 7}, {1, 3, 5, 2}, {7, 3, 8, 5}, {8, 4, 5, 3}]

print("The original list is : " + str(test_list))

res = set.intersection(*test_list)

print("Intersected Sets : " + str(res))

Output:

The original list is : [{3, 5, 6, 7}, {1, 2, 3, 5}, {8, 3, 5, 7}, {8, 3, 4, 5}]
Intersected Sets : {3, 5}

Method 3: Using reduce() + and_ operator

In this, we will perform intersection using and_ operator and Python reduce() does the task of getting all the sets packed together for the required operation.

Python3

from operator import and_

from functools import reduce

test_list = [{5, 3, 6, 7}, {1, 3, 5, 2}, {7, 3, 8, 5}, {8, 4, 5, 3}]

print("The original list is : " + str(test_list))

res = set(reduce(and_, test_list))

print("Intersected Sets : " + str(res))

Output:

The original list is : [{3, 5, 6, 7}, {1, 2, 3, 5}, {8, 3, 5, 7}, {8, 3, 4, 5}]
Intersected Sets : {3, 5}

Last Updated :
24 Mar, 2023

Like Article

Save Article

If you don’t have Python 2.6 or higher, the alternative is to write an explicit for loop:

def set_list_intersection(set_list):
  if not set_list:
    return set()
  result = set_list[0]
  for s in set_list[1:]:
    result &= s
  return result

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print set_list_intersection(set_list)
# Output: set([1])

You can also use reduce:

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print reduce(lambda s1, s2: s1 & s2, set_list)
# Output: set([1])

However, many Python programmers dislike it, including Guido himself:

About 12 years ago, Python aquired lambda, reduce(), filter() and map(), courtesy of (I believe) a Lisp hacker who missed them and submitted working patches. But, despite of the PR value, I think these features should be cut from Python 3000.

So now reduce(). This is actually the one I’ve always hated most, because, apart from a few examples involving + or *, almost every time I see a reduce() call with a non-trivial function argument, I need to grab pen and paper to diagram what’s actually being fed into that function before I understand what the reduce() is supposed to do. So in my mind, the applicability of reduce() is pretty much limited to associative operators, and in all other cases it’s better to write out the accumulation loop explicitly.

Время на прочтение
11 мин

Количество просмотров 94K

Python и теория множеств

В Python есть очень полезный тип данных для работы с множествами – это set. Об этом типе данных, примерах использования, и небольшой выдержке из теории множеств пойдёт речь далее.

Следует сразу сделать оговорку, что эта статья ни в коем случае не претендует на какую-либо математическую строгость и полноту, скорее это попытка доступно продемонстрировать примеры использования множеств в языке программирования Python.

  • Множество
  • Множества в Python
    • Хешируемые объекты
  • Свойства множеств
    • Принадлежность множеству
    • Мощность множества
    • Перебор элементов множества
  • Отношения между множествами
    • Равные множества
    • Непересекающиеся множества
    • Подмножество и надмножество
  • Операции над множествами
    • Объединение множеств
    • Добавление элементов в множество
    • Пересечение множеств
    • Разность множеств
    • Удаление элементов из множества
    • Симметрическая разность множеств
  • Заключение
  • Полезные ссылки

Множество

Множество – это математический объект, являющийся набором, совокупностью, собранием каких-либо объектов, которые называются элементами этого множества. Или другими словами:

Множество – это не более чем неупорядоченная коллекция уникальных элементов.

Что значит неупорядоченная? Это значит, что два множества эквивалентны, если содержат одинаковые элементы.

Элементы множества должны быть уникальными, множество не может содержать одинаковых элементов. Добавление элементов, которые уже есть в множестве, не изменяет это множество.

Множества, состоящие из конечного числа элементов, называются конечными, а остальные множества – бесконечными. Конечное множество, как следует из названия, можно задать перечислением его элементов. Так как темой этой статьи является практическое использование множеств в Python, то я предлагаю сосредоточиться на конечных множествах.

Множества в Python

Множество в Python можно создать несколькими способами. Самый простой – это задать множество перечислением его элементов в фигурных скобках:

fruits = {"banana", "apple", "orange"}

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

wrong_empty_set = {}
print(type(wrong_empty_set))

# Вывод
<class "dict">

Для создания пустого множества нужно непосредственно использовать set():

correct_empty_set = set()
print(type(correct_empty_set))

# Вывод
<class "set">

Также в set() можно передать какой-либо объект, по которому можно проитерироваться (Iterable):

color_list = ["red", "green", "green", "blue", "purple", "purple"]
color_set = set(color_list)
print(color_set)

# Вывод (порядок может быть другим):
{"red", "purple", "blue", "green"}

Ещё одна возможность создания множества – это использование set comprehension. Это специальная синтаксическая конструкция языка, которую иногда называют абстракцией множества по аналогии с list comprehension (Списковое включение).

numbers = [1, 2, 2, 2, 3, 3, 4, 4, 5, 6]

# Единственное отличие со списковыми включениями - это
# использование фигурных скобок вместо квадратных
even_numbers = {
    number for number in numbers
    if number % 2 == 0
}
print(even_numbers)

# Вывод (порядок может быть другим):
{2, 4, 6}

Хешируемые объекты

Существует ограничение, что элементами множества (как и ключами словарей) в Python могут быть только так называемые хешируемые (Hashable) объекты. Это обусловлено тем фактом, что внутренняя реализация set основана на хеш-таблицах. Например, списки и словари – это изменяемые объекты, которые не могут быть элементами множеств. Большинство неизменяемых типов в Python (int, float, str, bool, и т.д.) – хешируемые. Неизменяемые коллекции, например tuple, являются хешируемыми, если хешируемы все их элементы.

# Множество кортежей (tuple)
records = {
    ("Москва", 17_200_000), 
    ("Санкт-Петербург", 5_400_000), 
    ("Новосибирск", 1_600_000),
    ("Москва", 17_200_000),
}

for city, population in records:
    print(city)

# Вывод (порядок может быть другим):
Москва
Новосибирск
Санкт-Петербург

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

class City:
    def __init__(self, name: str):
        self.name = name

    def __repr__(self) -> str:
        """ Определим метод __repr__ для наглядности следующих примеров
        """
        return f'City("{self.name}")'

print(City("Moscow") == City("Moscow"))

# Вывод:
False

cities = {City("Moscow"), City("Moscow")}
print(cities)

# Вывод
{City("Moscow"), City("Moscow")}

Скорее всего мы предполагаем, что объекты City("Moscow") должны быть равными, и следовательно в множестве cities должен находиться один объект.
Этого можно добиться, если определить семантику равенства для объектов класса City:

class City:
    def __init__(self, name: str):
        # Атрибут name не должен изменяться, пока объект существует
        # Для простоты пометим этот атрибут как внутренний
        self._name = name

    def __hash__(self) -> int:
        """ Хеш от объекта
        """
        return hash((self._name, self.__class__))

    def __eq__(self, other) -> bool:
        """ Определяем семантику равентсва (оператор ==)
        """
        if not isinstance(other, self.__class__):
            return False
        return self._name == other._name

    def __repr__(self) -> str:
        """ Определим метод __repr__ для наглядности следующих примеров
        """
        return f'City("{self._name}")'

Чтобы протокол хеширования работал без явных и неявных логических ошибок, должны выполняться следующие условия:

  • Хеш объекта не должен изменяться, пока этот объект существует
  • Равные объекты должны возвращать одинаковый хеш

moscow = City("Moscow")
moscow_again = City("Moscow")

print(moscow == moscow_again and hash(moscow) == hash(moscow_again))
# Вывод:
True

# Теперь множество городов работает более логично и интуитивно
cities = {City("Moscow"), City("Kazan"), City("Moscow")}
print(cities)

# Вывод (порядок может быть другим):
{City("Kazan"), City("Moscow")}

Свойства множеств

Тип set в Python является подтипом Collection (про коллекции), из данного факта есть три важных следствия:

  • Определена операция проверки принадлежности элемента множеству
  • Можно получить количество элементов в множестве
  • Множества являются iterable-объектами

Принадлежность множеству

Проверить принадлежит ли какой-либо объект множеству можно с помощью оператора in. Это один из самых распространённых вариантов использования множеств. Такая операция выполняется в среднем за O(1) с теми же оговорками, которые существуют для хеш-таблиц.

tremendously_huge_set = {"red", "green", "blue"}

if "green" in tremendously_huge_set:
    print("Green is there!")
else:
    print("Unfortunately, there is no green...")

# Вывод:
Green is there!

if "purple" in tremendously_huge_set:
    print("Purple is there!")
else:
    print("Unfortunately, there is no purple...")

# Вывод:
Unfortunately, there is no purple...

Мощность множества

Мощность множества – это характеристика множества, которая для конечных множеств просто означает количество элементов в данном множестве. Для бесконечных множеств всё несколько сложнее.

even_numbers = {i for i in range(100) if i % 2 == 0}

# Мощность множества
cardinality = len(even_numbers)
print(cardinality)

# Вывод:
50

Перебор элементов множества

Как уже было отмечено выше, множества поддерживают протокол итераторов, таким образом любое множество можно использовать там, где ожидается iterable-объект.

colors = {"red", "green", "blue"}

# Элементы множества можно перебрать с помощью цикла for
for color in colors:
    print(color)

# Вывод (порядок может быть другим):
red
green
blue

# Множества можно использовать там, где ожидается iterable-объект
color_counter = dict.fromkeys(colors, 1)
print(color_counter)

# Вывод (порядок может быть другим):
{"green": 1, "red": 1, "blue": 1}

Отношения между множествами

Между множествами существуют несколько видов отношений, или другими словами взаимосвязей. Давайте рассмотрим возможные отношения между множествами в этом разделе.

Равные множества

Тут всё довольно просто – два множества называются равными, если они состоят из одних и тех же элементов. Как следует из определения множества, порядок этих элементов не важен.

my_fruits = {"banana", "apple", "orange", "orange"}
your_fruits = {"apple", "apple", "banana", "orange", "orange"}
print(my_fruits == your_fruits)

# Вывод:
True

Непересекающиеся множества

Если два множества не имеют общих элементов, то говорят, что эти множества не пересекаются. Или другими словами, пересечение этих множеств является пустым множеством.

even_numbers = {i for i in range(10) if i % 2 == 0}
odd_numbers = {i for i in range(10) if i % 2 == 1}

# Очевидно, что множества чётных и нечётных чисел не пересекаются
if even_numbers.isdisjoint(odd_numbers):
    print("Множества не пересекаются!")

# Вывод:
Множества не пересекаются!

Подмножество и надмножество

Подмножество множества S – это такое множество, каждый элемент которого является также и элементом множества S. Множество S в свою очередь является надмножеством исходного множества.

# Множество чисел Фибоначчи меньших 100
fibonacci_numbers = {0, 1, 2, 3, 34, 5, 8, 13, 21, 55, 89}

# Множество натуральных чисел меньших 100
natural_numbers = set(range(100))

# Множество чисел Фибоначчи является подмножеством множества 
# натуральных чисел
if fibonacci_numbers.issubset(natural_numbers):
    print("Подмножество!")

# Вывод:
Подмножество!

# В свою очередь множество натуральных чисел является
# надмножеством множества чисел Фибоначчи
if natural_numbers.issuperset(fibonacci_numbers):
    print("Надмножество!")

# Вывод:
Надмножество!

Пустое множество является подмножеством абсолютно любого множества.

empty = set()

# Методы issubset и issuperset могут принимать любой iterable-объект
print(
    empty.issubset(range(100))
    and empty.issubset(["red", "green", "blue"])
    and empty.issubset(set())
)

# Вывод:
True

Само множество является подмножеством самого себя.

natural_numbers = set(range(100))

if natural_numbers.issubset(natural_numbers):
    print("Подмножество!")

# Вывод:
Подмножество!

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

Рассмотрим основные операции, опредяляемые над множествами.

Объединение множеств

Объединение множеств – это множество, которое содержит все элементы исходных множеств. В Python есть несколько способов объединить множества, давайте рассмотрим их на примерах.

my_fruits = {"apple", "orange"}
your_fruits = {"orange", "banana", "pear"}

# Для объединения множеств можно использовать оператор `|`,
# оба операнда должны быть объектами типа set
our_fruits = my_fruits | your_fruits
print(our_fruits)

# Вывод (порядок может быть другим):
{"apple", "banana", "orange", "pear"}

# Также можно использовать ментод union.
# Отличие состоит в том, что метод union принимает не только
# объект типа set, а любой iterable-объект
you_fruit_list: list = list(your_fruits)
our_fruits: set = my_fruits.union(you_fruit_list)
print(our_fruits)

# Вывод (порядок может быть другим):
{"apple", "banana", "orange", "pear"}

Добавление элементов в множество

Добавление элементов в множество можно рассматривать как частный случай объединения множеств за тем исключением, что добавление элементов изменяет исходное множество, а не создает новый объект. Добавление одного элемента в множество работает за O(1).

colors = {"red", "green", "blue"}

# Метод add добаляет новый элемент в множество
colors.add("purple")
# Добавление элемента, который уже есть в множестве, не изменяет
# это множество
colors.add("red")
print(colors)

# Вывод (порядок может быть другим):
{"red", "green", "blue", "purple"}

# Метод update принимает iterable-объект (список, словарь, генератор и т.п.)
# и добавляет все элементы в множество
numbers = {1, 2, 3}
numbers.update(i**2 for i in [1, 2, 3])
print(numbers)

# Вывод (порядок может быть другим):
{1, 2, 3, 4, 9}

Пересечение множеств

Пересечение множеств – это множество, в котором находятся только те элементы, которые принадлежат исходным множествам одновременно.

def is_prime(number: int) -> bool:
    """ Возвращает True, если number - это простое число
    """
    assert number > 1
    return all(number % i for i in range(2, int(number**0.5) + 1))

def is_fibonacci(number: int) -> bool:
    """ Возвращает True, если number - это число Фибоначчи
    """
    assert number > 1
    a, b = 0, 1
    while a + b < number:
        a, b = b, a + b
    return a + b == number

# Множество простых чисел до 100
primes = set(filter(is_prime, range(2, 101)))

# Множество чисел Фибоначчи до 100
fibonacci = set(filter(is_fibonacci, range(2, 101)))

# Множество простых чисел до 100, которые одновременно являются
# числами Фибоначчи
prime_fibonacci = primes.intersection(fibonacci)

# Или используя оператор `&`, который определён для множеств
prime_fibonacci = fibonacci & primes

print(prime_fibonacci)

# Вывод (порядок может быть другим):
{2, 3, 5, 13, 89}

При использовании оператора & необходимо, чтобы оба операнда были объектами типа set. Метод intersection, в свою очередь, принимает любой iterable-объект. Если необходимо изменить исходное множество, а не возращать новое, то можно использовать метод intersection_update, который работает подобно методу intersection, но изменяет исходный объект-множество.

Разность множеств

Разность двух множеств – это множество, в которое входят все элементы первого множества, не входящие во второе множество.

i_know: set = {"Python", "Go", "Java"}
you_know: dict = {
    "Go": 0.4, 
    "C++": 0.6, 
    "Rust": 0.2, 
    "Java": 0.9
}

# Обратите внимание, что оператор `-` работает только
# для объектов типа set
you_know_but_i_dont = set(you_know) - i_know
print(you_know_but_i_dont)

# Вывод (порядок может быть другим):
{"Rust", "C++"}

# Метод difference может работать с любым iterable-объектом,
# каким является dict, например
i_know_but_you_dont = i_know.difference(you_know)
print(i_know_but_you_dont)

# Вывод:
{"Python"}

Удаление элементов из множества

Удаление элемента из множества можно рассматривать как частный случай разности, где удаляемый элемент – это одноэлементное множество. Следует отметить, что удаление элемента, как и в аналогичном случае с добавлением элементов, изменяет исходное множество. Удаление одного элемента из множества имеет вычислительную сложность O(1).

fruits = {"apple", "orange", "banana"}

# Удаление элемента из множества. Если удаляемого элемента
# нет в множестве, то ничего не происходит
fruits.discard("orange")
fruits.discard("pineapple")
print(fruits)

# Вывод (порядок может быть другим):
{"apple", "banana"}

# Метод remove работает аналогично discard, но генерирует исключение,
# если удаляемого элемента нет в множестве
fruits.remove("pineapple")  # KeyError: "pineapple"

Также у множеств есть метод differenсe_update, который принимает iterable-объект и удаляет из исходного множества все элементы iterable-объекта. Этот метод работает аналогично методу difference, но изменяет исходное множество, а не возвращает новое.

numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
even_numbers_under_100 = (i for i in range(1, 101) if i % 2 == 0)
numbers.difference_update(even_numbers_under_100)
print(numbers)

# Вывод (порядок может быть другим):
{1, 3, 5, 7, 9}

Симметрическая разность множеств

Симметрическая разность множеств – это множество, включающее все элементы исходных множеств, не принадлежащие одновременно обоим исходным множествам. Также симметрическую разность можно рассматривать как разность между объединением и пересечением исходных множеств.

non_positive = {-3, -2, -1, 0}
non_negative = {0, 1, 2, 3}

# Обратите внимание, что оператор `^` может применяться
# только для объектов типа set
non_zero = non_positive ^ non_negative
print(non_zero)

# Вывод (порядок может быть другим):
{-1, -2, -3, 1, 2, 3}

Как видно из примера выше, число 0 принадлежит обоим исходным множествам, и поэтому оно не входит в результирующее множество. Для операции симметрической разности, помимо оператора ^, также существует два специальных метода – symmetric_difference и symmetric_difference_update. Оба этих метода принимают iterable-объект в качестве аргумента, отличие же состоит в том, что symmetric_difference возвращает новый объект-множество, в то время как symmetric_difference_update изменяет исходное множество.

non_positive = {-3, -2, -1, 0}
non_negative = range(4)

non_zero = non_positive.symmetric_difference(non_negative)
print(non_zero)

# Вывод (порядок может быть другим):
{-1, -2, -3, 1, 2, 3}

# Метод symmetric_difference_update изменяет исходное множество
colors = {"red", "green", "blue"}
colors.symmetric_difference_update(["green", "blue", "yellow"])
print(colors)

# Вывод (порядок может быть другим):
{"red", "yellow"}

Заключение

Я надеюсь, мне удалось показать, что Python имеет очень удобные встроенные средства для работы с множествами. На практике это часто позволяет сократить количество кода, сделать его выразительнее и легче для восприятия, а следовательно и более поддерживаемым. Я буду рад, если у вас есть какие-либо конструктивные замечания и дополнения.

Полезные ссылки

Множества (Статья на Википедии)
Документация по типу set
Iterable-объекты (Глоссарий Python)
Hashable-объекты (Глоссарий Python)
Sets in Python
Set Theory: the Method To Database Madness

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

Создание

Перед тем как начать работу с множеством, необходимо для начала его создать. Сделать это можно, просто присвоив переменной последовательность значений, выделив их фигурными скобками. Следующий пример показывает код, в котором создается множество целых чисел под названием a, после функция print выводит на экран его содержимое.

a = {1, 2, 0, 1, 3, 2}
print(a)

{0, 1, 2, 3}

Как можно заметить, все элементы полученной последовательности являются уникальными, без повторений. Существует и другой способ создания множеств, который подразумевает использование метода set. Аргументом этой функции может быть набор неких данных или даже строка с текстом, как это показано в следующем примере.

a = set('data')
print(a)

{'d', 'a', 't'}

В результате выполнения этого кода, программа заполняет новое множество уникальными символами из входной строки. Содержимое набора также выводится на экран.

Использование

Обычно используется для следующих операций:

  • Проверка, есть ли данное значение в множестве. Для этого используется in.
    a = {0, 1, 2, 3}
    print(2 in a)
    
    True
  • Наоборот, проверка отсутствия. Используется not in.
    a = {0, 1, 2, 3}
    print(2 not in a)
    
    False
  • Перебор всех элементов.
    for a in {0, 1, 2}:
        print(a)
    
    0
    1
    2

Генератор

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

Следующий код демонстрирует генерацию множества a с циклом for для нескольких чисел.

a = {i for i in [1, 2, 0, 1, 3, 2]}
print(a)

{0, 1, 2, 3}

Как и прежде, метод print показывает содержимое полученного набора значений, где нет повторений, поскольку одинаковые числа автоматически удаляются.

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

Для управления содержимым множеств в языке Python присутствуют специальные методы, дающие возможность добавлять и удалять отдельные элементы.

Получение размера

Узнать точное количество элементов, входящих в состав множества, поможет метод len, принимающий в качестве аргумента набор данных. Функция print выводит результат.

a = {0, 1, 2, 3}
print(len(a))

4

Добавление элемента

Чтобы внести новые значения, потребуется вызывать метод add. Аргументом в данном случае будет добавляемый элемент последовательности. В примере кода на Python добавим в множество элемент со значением 4.

a = {0, 1, 2, 3}
a.add(4)
print(a)

{0, 1, 2, 3, 4}

Удаление элемента

Для удаления элементов из множества используются следующие функции в Python (кроме очистки, которая будет рассмотрена ниже):

  • remove — удаление элемента с генерацией исключения в случае, если такого элемента нет;
  • discard — удаление элемента без генерации исключения, если элемент отсутствует;
  • pop — удаление первого элемента, генерируется исключение при попытке удаления из пустого множества.

Избавиться от лишних значений в наборе данных с помощью remove. В качестве входного параметра здесь выступает элемент, который нужно удалить (в примере удалим число со значением 3).

a = {0, 1, 2, 3}
a.remove(3)
print(a)

{0, 1, 2}

По поводу функции pop хотелось бы отметить, что так как множества не упорядочены, то удалится случайный элемент, который будет находиться в памяти первым. Но если они в памяти хранятся в отсортированном виде, что не факт, то скорее всего будет удален элемент с наименьшим значением. Но на это не стоит рассчитывать.

Полная очистка

Иногда необходимо полностью убрать все элементы. Чтобы не удалять каждый элемент отдельно, используется метод clear, не принимающий аргументов. Если вывести содержимое после этой операции, на экране появится только его название.

a = {0, 1, 2, 3}
a.clear()
print(a)

set()

В результате получили пустое множество.

Сортировка

Порядок следования элементов не учитывается. Поэтому нет смысла говорить о сортировке множеств в Python 3.

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

В начале рассмотрим, что будет с элементами разных типов данных в одном множестве. Такие элементы не должны сортироваться. Если мы будем выводить элементы с помощью команды print, то они выводятся примерно следующим образом:

a = {0, 1, 12, 'b', 'ab', 3, 2, 'a'}
print(a)

{0, 1, 'b', 3, 2, 12, 'ab', 'a'}

Как видим, у нас вывелись не отсортированные значения, если повторить запуск, то порядок будет меняться. Но это только в том случае, если перемешаны элементы разного типа.

Посмотрим, что будет, если попытаемся вывести только числа:

a = {0, 1, 12, 3, 2}
print(a)

{0, 1, 2, 3, 12}

Все элементы выведены упорядоченно. Теперь посмотрим что будет если преобразовать в список:

a = {0, 1, 12, 3, 2}
b = list(a)
print(b)

[0, 1, 2, 3, 12]

Аналогично, в список значения записались отсортированными по возрастанию.

Получается, что элементы хранятся в памяти в упорядоченном виде, если они одного типа. Но лучше не стоит на это расчитывать, алгоритмы Python могут поменяться.

Если вам нужно получить отсортированный список из множества, лучше воспользоваться для верности функцией sort. Элементы будут точно отсортированы. Ваш код будет понятен для других.

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

Помимо различных манипуляций с элементами множеств, существуют еще и операции над ними, позволяющие одной строчкой кода выполнять сложные преобразования.

Рассмотрим операции с множествами доступные в Python 3.

Объединение

Чтобы объединить все элементы двух разных множеств, стоит воспользоваться методом union на одном из объектов. Следующий пример демонстрирует работу данной функции, где создается последовательность чисел под именем c.

a = {0, 1, 2, 3}
b = {4, 3, 2, 1}
c = a.union(b)
print(c)

{0, 1, 2, 3, 4}

Добавление

Чтобы добавить все элементы из одного множества к другому, необходимо вызывать метод update на первом объекте. Таким образом можно перенести уникальные данные из одного набора чисел в другой, как это показано в следующем примере.

a = {0, 1, 2, 3}
b = {4, 3, 2, 1}
a.update(b)
print(a)

{0, 1, 2, 3, 4}

Пересечение

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

a = {0, 1, 2, 3}
b = {4, 3, 2, 1}
c = a.intersection(b)
print(c)

{1, 2, 3}

Разность

Чтобы вычислить разность для двух разных множеств, необходимо воспользоваться методом difference. Функция позволяет найти элементы, уникальные для второго набора данных, которых в нем нет. Следующий код демонстрирует эту операцию.

a = {0, 1, 2, 3}
b = {4, 3, 2, 1}
c = a.difference(b)
print(c)

{0}

Отношения между множествами

Для определения подмножеств и надмножеств существуют специальные функции, возвращающие True или False в зависимости от результата выполнения.

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

Чтобы выяснить, является ли множество a подмножествомb, стоит попробовать вывести на экран результат выполнения метода issubset, как в следующем примере. Так как не все элементы набора чисел a присутствуют в b, функция вернет False.

a = {0, 1, 2, 3, 4}
b = {3, 2, 1}
print(a.issubset(b))

False

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

Чтобы узнать, является ли множество a надмножеством b, необходимо вызвать метод issuperset и вывести результат его работы на экран. Поскольку все элементы набора чисел b присутствуют в a, функция возвращает True.

a = {0, 1, 2, 3, 4}
b = {3, 2, 1}
print(a.issuperset(b))

True

Тип frozenset

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

a = frozenset({"hello", "world"})
print(a)

frozenset({'hello', 'world'})

Поскольку содержимое frozenset должно всегда оставаться статичным, перечень функций, с которыми такое множество может взаимодействовать, имеет ограничения.

Преобразование множеств

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

Строка

Для преобразования множества в строку используется конкатенация текстовых значений, которую обеспечивает функция join. В этом случае ее аргументом является набор данных в виде нескольких строк. Запятая в кавычках выступает в качестве символа, разделяющего значения. Метод type возвращает тип данных объекта в конце приведенного кода.

a = {'set', 'str', 'dict', 'list'}
b = ','.join(a)
print(b)
print(type(b))

set,dict,list,str
<class 'str'>

Словарь

Чтобы получить из множества словарь, следует передать функции dict набор из нескольких пар значений, в каждом из которых будет находиться ключ. Метод print демонстрирует на экране содержимое полученного объекта, а type отображает его тип.

a = {('a', 2), ('b', 4)}
b = dict(a)
print(b)
print(type(b))

{'b': 4, 'a': 2}
<class 'dict'>

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

  1. ключ будущего словаря;
  2. значение, соответствующее ключу.

Список

По аналогии с предыдущими преобразованиями можно получить список неких объектов. На этот раз используется метод list, получающий в качестве аргумента множество a. На выходе функции print отображаются уникальные значения для изначального набора чисел.

a = {1, 2, 0, 1, 3, 2}
b = list(a)
print(b)
print(type(b))

[0, 1, 2, 3]
<class 'list'>

Резюме

Следующая таблица отображает краткую сводку по всем пройденным функциям, включая их названия и назначение.

Название Назначение
len Получение размера
add Добавление элемента
remove Удаление элемента
clear Очистка
union Объединение
update Добавление всех элементов одного множества в другое
intersection Нахождение множества, элементы которого находятся на пересечении двух множеств
difference Нахождение множества, элементы которого входят в первое, но не входят во второе множество
issubset Проверка, является ли множество подмножеством
issuperset Проверка, является ли множество надмножеством

Заключение

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

Тип данных set в Python поддерживает все операции, которые проводятся над множествами в математике:

  • пересечение;
  • объединение;
  • дополнение;
  • разность;
  • симметрическую разность.

Множества set обладают рядом особенностей, которые значительно отличают их от других типов данных.

1. В Python два вида множеств – обычное, изменяемое set и замороженное, неизменяемое frozenset. Замороженные множества нельзя изменить после создания, но все операции по объединению, пересечению и разности они поддерживают: результатом этих операций тоже будут frozenset.

2. Множество может включать в себя только неизменяемые типы данных – строки, числа, кортежи (в любой комбинации). Попытка добавить в множество список, словарь или изменяемое множество приведет к ошибке:

        >>> a_set = {[2, 3], [4, 7]}
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
TypeError: unhashable type: 'list'

    

Неизменяемое множество frozenset, в отличие от set, может входить в изменяемое множество:

        >>> set_a = {1, 2, 3}
>>> set_b = frozenset({4, 5, 6})
>>> set_c = {7, 8, 9, set_a}
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> set_c = {7, 8, 9, set_b}
>>> print(set_c)
{8, 9, frozenset({4, 5, 6}), 7}

    

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

        >>> set_a = set('123')
>>> print(set_a)
{'3', '2', '1'}
>>> print(set[1])
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
TypeError: 'type' object is not subscriptable

    

4. Поскольку элементы множества не имеют индексов, срезы при работе с set тоже использовать нельзя:

        >>> set_a = {1, 3, 4, 5, 2, 9, 7}
>>> print(set_a[2:5])
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
TypeError: 'set' object is not subscriptable

    

5. Все элементы множества – уникальны, повторяющиеся данные в set игнорируются; это свойство множеств может пригодиться для решения практических задач:

        >>> my_set = {2, 2, 2}
>>> print(my_set)
{2}

    

6. Множества не поддерживают конкатенацию и повторение:

        >>> set_a = {1, 3, 5}
>>> set_b = {9, 4, 8}
>>> print(set_a + set_b)
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'set' and 'set'
>>> print(set_a * 2)
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'set' and 'int'

    

7. Множества занимают значительно больший объем памяти, нежели списки и кортежи. По этой причине лучше не использовать множества для решения задач с лимитом на объем памяти:

        >>> from sys import getsizeof
>>> number = 100500
>>> my_list = list(range(number))
>>> my_tuple = tuple(range(number))
>>> my_set = set(range(number))
>>> my_list_size = getsizeof(my_list)
>>> my_tuple_size = getsizeof(my_tuple)
>>> my_set_size = getsizeof(my_set)
>>> print(f'Размер списка: {round(my_list_size / 1024 / 1024, 3)} Мб')
Размер списка: 0.431 Мб
>>> print(f'Размер кортежа: {round(my_tuple_size / 1024 / 1024, 3)} Мб')
Размер кортежа: 0.383 Мб
>>> print(f'Размер множества: {round(my_set_size / 1024 / 1024, 3)} Мб')
Размер множества: 2.0 Мб

    

8. Хотя множества занимают гораздо больший объем памяти, чем списки и кортежи, работают они гораздо быстрее. Этот код сравнивает время, затраченное на проведение операции над списком, кортежем и множеством с одинаковым количеством элементов:

        from time import time
number = 15000
my_set = set(range(number))
my_list = list(range(number))
my_tuple = tuple(range(number))

t = time()
for i in range(number):
    if i in my_list:
        pass
print(f"Операция со списком: {time() - t} секунд")
my_list.clear()

t = time()
for i in range(number):
    if i in my_tuple:
        pass
print(f"Операция с кортежeм: {time() - t} секунд")

t = time()
for i in range(number):
    if i in my_set:
        pass
print(f"Операция со множеством: {time() - t} секунд")
my_set.clear()

    

Результат:

        Операция со списком: 1.810847282409668 секунд
Операция с кортежeм: 1.6490623950958252 секунд
Операция со множеством: 0.0013110637664794922 секунд

    

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

Пустое множество можно создать только одним способом, с помощью set():

        >>> my_set = set()
>>> print(type(my_set))
<class 'set'>

    

Попытка создать пустое множество с помощью фигурных скобок {} обречена на провал – вместо set будет создан словарь dict:

        >>> my_set = {}
>>> print(type(my_set))
<class 'dict'>

    

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

Способ 1: Перечисление элементов

Для создания множества нужные элементы перечисляют через запятую в фигурных скобках:

        >>> set_a = {3, 7, 9, 0, 2, 1}
>>> set_b = {'а', 'б', 'в', 'г'}
>>> set_c = {'Мастер и Маргарита', 450, 1250, 'переплет'}
>>> set_d = {2, 4, 5, (2, 9, 0)}

    

Способ 2: Преобразование других типов данных

Множество можно создать на основе символов либо слов строки:

        >>> print(set('абырвалг'))
{'р', 'в', 'л', 'г', 'б', 'а', 'ы'}
>>> print(set('Множества в Python'.split()))
{'Множества', 'в', 'Python'}

    

Множество из списка:

        >>> print(set([3, 6, 4, 5, 5]))
{3, 4, 5, 6}

    

Множество на основе кортежа:

        >>> print(set(('красный', 'синий', 'зеленый')))
{'зеленый', 'красный', 'синий'}

    

При создании множества из dict от словаря останутся только ключи:

        >>> print(set({'артикул': 'А123', 'цвет': 'черный'}))
{'артикул', 'цвет'}

    

В отличие от символов строк, число нельзя автоматически разбить на отдельные цифры и преобразовать во множество напрямую:

        >>> print(set(123))
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
TypeError: 'int' object is not iterable

    

Но с применением str преобразование проходит без ошибок:

        >>> print(set(str(1812)))
{'8', '2', '1'}

    

Способ 3: Генераторы множеств

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

        >>> print({i ** 2 for i in range(15)})
{0, 1, 64, 121, 4, 36, 100, 196, 9, 169, 16, 49, 81, 144, 25}

    

В генераторах можно использовать любые условия:

        >>> print({int(i) for i in '3в2о7ыр3р74ртрчфрежр4рфф23468795323' if i.isdigit() and int(i) < 7})
{2, 3, 4, 5, 6}

    

В генератор можно включить любые дополнительные функции, например, ввод input() и функцию ord() для возвращения числового кода символа из таблицы Unicode:

        >>> print({ord(i) for i in input() if i.isalpha()})
ewr73694yrhf897349ugg05fhshcvnaWQXXldoaxsd
{81, 87, 88, 97, 99, 100, 101, 102, 103, 104, 108, 110, 111, 114, 115, 117, 118, 119, 120, 121}

    

Помимо условия if, в генератор можно добавить обработку else:

        >>> set_a = {i ** 2 if i % 2 == 0 else i ** 3 for i in (map(int, input().split()))}
2 5 12 13 4 56 71 33 9 10
>>> print(set_a)
{3136, 35937, 4, 100, 144, 16, 2197, 357911, 729, 125}

    

Стандартные методы множеств в Python

Множества поддерживают ряд стандартных методов, общих для большинства коллекций Python, и имеют несколько собственных, уникальных для типа set. Начнем с общих методов.

Длина, сумма, min и max элементы

Эти методы работают со множествами точно так же, как и со списками и кортежами:

        >>> set_a = {2, 4, 5, 6, 1, 9, 7, 12}
>>> print(f'Количество элементов: {len(set_a)}, сумма элементов: {sum(set_a)}')
Количество элементов: 8, сумма элементов: 46
>>> print(f'Минимальный элемент: {min(set_a)}, максимальный элемент: {max(set_a)}')
Минимальный элемент: 1, максимальный элемент: 12

    

Принадлежность элемента множеству

        >>> my_set = {'математика', 'физика', 'химия'}
>>> print('математика' in my_set)
True
>>> print('биология' not in my_set)
True

    

Сортировка

Как и в случае с кортежами, результатом сортировки множества будет список:

        >>> numbers = {25, 15, 7, 8, 19, 34, 52, 0, 12, 59, 91, 4}
>>> print(sorted(numbers))
[0, 4, 7, 8, 12, 15, 19, 25, 34, 52, 59, 91]
>>> print(sorted(numbers, reverse=True))
[91, 59, 52, 34, 25, 19, 15, 12, 8, 7, 4, 0]

    

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

Множества можно сравнивать с помощью операторов == и !=:

        >>> set_a = {5, 1, 4, 8, 6, 9}
>>> set_b = {6, 2, 5, 9, 7, 10}
>>> print(set_b != set_a)
True

    

Другие операторы сравнения, например > и <, дают неожиданный на первый взгляд результат:

        >>> set_a = {1, 2, 3}
>>> set_b = {4, 5, 6, 7}
>>> print(set_b > set_a)
False

    

Это связано с тем, что при сравнении множеств Python определяет, является ли одно из них под- или надмножеством другого (подробнее об этом – ниже):

        >>> set_a = {1, 2, 3}
>>> set_b = {1, 2, 3, 4}
>>> print(set_b > set_a)
True

    

Добавление элемента

Метод add() добавляет во множество новый элемент:

        >>> letters = {'а', 'б', 'в'}
>>> letters.add('г')
>>> print(letters)
{'г', 'в', 'а', 'б'}

    

Несколько элементов можно добавить с помощью цикла for (мы рассмотрим его в следующей статье) или с помощью генератора:

        >>> set_a = set()
>>> gen = {set_a.add(i) for i in range(12)}
>>> print(set_a)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}

    

Удаление элемента

Для удаления элемента нужно воспользоваться одним из поддерживаемых методов:

1. remove() – возвращает сообщение об ошибке, если элемент не будет найден:

        >>> my_set = {1, 2, 3}
>>> my_set.remove(2)
>>> print(my_set)
{1, 3}

    

2. discard() – безопасный метод, не приводит к ошибке в случае отсутствия элемента:

        >>> my_set = {'красный', 'черный', 'синий'}
>>> my_set.discard('синий')
>>> print(my_set)
{'красный', 'черный'}
>>> my_set.discard('розовый')
>>> 

    

3. pop() – в отличие от аналогичного списочного метода, удаляет случайный элемент и возвращает его значение:

        >>> my_set = {2, 4, 6, 1, 12}
>>> print(my_set.pop())
1

    

4. Метод clear() удаляет все элементы множества сразу – так можно освободить оперативную память после завершения операции с объемным set:

        >>> my_set = {6, 2, 9, 0}
>>> my_set.clear()
>>> print(my_set)
set()

    

Специальные методы множеств

Как уже упоминалось выше, объекты set в Python поддерживают все операции, которые проводятся над множествами в математике. Эти операции делятся на три группы:

  • Не изменяющие исходные множества – эти методы возвращают новые множества.
  • Изменяющие исходные множества.
  • Определяющие, являются ли множества под(над)множествами друг друга – эти методы возвращают True или False.

Рассмотрим методы из этих групп подробнее.

Методы, не изменяющие исходные множества

Объединение множеств

Объединение множеств union () – это множество, которое состоит из элементов, входящих в состав хотя бы одного из объединяемых множеств:

        >>> set_a = {1, 2, 3}
>>> set_b = {4, 5, 6}
>>> print(set_a.union(set_b))
{1, 2, 3, 4, 5, 6}

    

Вместо union() можно использовать оператор |:

        >>> set_a = {'синий', 'розовый', 'черный'}
>>> set_b = {'зеленый', 'красный', 'желтый'}
>>> print(set_a | set_b)
{'синий', 'красный', 'желтый', 'розовый', 'черный', 'зеленый'}

    

Пересечение множеств

Пересечением множеств intersection() называется множество, которое состоит из элементов, входящих в каждое из пересекающихся множеств:

        >>> set_a = {2, 3, 5, 1, 8}
>>> set_b = {2, 5, 0, 9, 7}
>>> print(set_a.intersection(set_b))
{2, 5}

    

Вместо intersection() можно использовать оператор &:

        >>> set_a = {'a', 'b', 'd', 'k'}
>>> set_b = {'v', 'b', 'e', 'k'}
>>> print(set_a & set_b)
{'k', 'b'}

    

Разность множеств

Разностью множеств difference() называется множество, в которое входят все элементы первого множества, не входящие во второе множество:

        >>> set_a = {4, 9, 7, 2, 1, 0}
>>> set_b = {5, 8, 3, 1, 4, 9}
>>> print(set_a.difference(set_b))
{0, 2, 7}

    

Вместо difference() можно использовать оператор - :

        >>> set_a = {'a', 'b', 'g', 'j'}
>>> set_b = {'f', 'b', 's', 'g'}
>>> print(set_a - set_b)
{'a', 'j'}

    

Симметрическая разность

Симметрической разностью symmetric_difference() называется множество, состоящее из элементов, которые не входят в первое и второе множество одновременно:

        >>> set_a = {1, 2, 3, 4}
>>> set_b = {6, 8, 4, 3}
>>> print(set_a.symmetric_difference(set_b))
{1, 2, 6, 8}

    

В качестве оператора симметрической разности используется ^:

        >>> set_a = {'h', 'v', 'a', 'w', 'q'}
>>> set_b = {'v', 'h', 'u', 'f', 'o'}
>>> print(set_a ^ set_b)
{'u', 'w', 'f', 'q', 'a', 'o'}

    

Методы, изменяющие исходные множества

Метод update()

Изменяет исходное множество по объединению:

        >>> set_a = {1, 2, 3}
>>> set_b = {4, 5, 6}
>>> set_a.update(set_b)
>>> print(set_a)
{1, 2, 3, 4, 5, 6}

    

Оператор метода update|=:

        >>> set_a = {'a', 'b', 'd'}
>>> set_b = {'c', 'e', 'f'}
>>> set_a |= set_b
>>> print(set_a)
{'b', 'c', 'f', 'a', 'e', 'd'}

    

Метод intersection_update()

Изменяет исходное множество по пересечению:

        >>> set_a = {1, 2, 3}
>>> set_b = {3, 4, 5}
>>> set_a.intersection_update(set_b)
>>> print(set_a)
{3}

    

Оператор intersection_update()&=:

        >>> set_a = {'a', 'b', 'd', 'q'}
>>> set_b = {'h', 'f', 'b', 'a'}
>>> set_a &= set_b
>>> print(set_a)
{'a', 'b'}

    

Метод difference_update()

Изменяет исходное множество по разности:

        >>> set_a = {3, 2, 7, 8, 0}
>>> set_b = {4, 5, 6, 3, 8}
>>> set_a.difference_update(set_b)
>>> print(set_a)
{0, 2, 7}

    

Оператор difference_update()-=:

        >>> set_a = {'v', 's', 'a', 'q', 'r'}
>>> set_b = {'d', 's', 'a', 'f', 'e'}
>>> set_a -= set_b
>>> print(set_a)
{'q', 'r', 'v'}

    

Метод symmetric_difference_update()

Изменяет исходное множество по симметрической разности:

        >>> set_a = {1, 2, 3, 4, 5}
>>> set_b = {8, 2, 4, 6, 1}
>>> set_a.symmetric_difference_update(set_b)
>>> print(set_a)
{3, 5, 6, 8}

    

Оператор symmetric_difference_update() ^=:

        >>> set_a = {'a', 'k', 'r', 'o', 'p'}
>>> set_b = {'d', 'a', '$', 'o', '@'}
>>> set_a ^= set_b
>>> print(set_a)
{'@', 'p', 'd', 'k', 'r', '$'}

    

Методы для определения под- и надмножеств

Множество set_a считается подмножеством set_b в том случае, если все элементы set_a входят в set_b. В свою очередь, множество set_b этом случае считается надмножеством set_a. При этом любое множество считается подмножеством самого себя, или нестрогим подмножеством.

Для определения под- и надмножеств в Python есть три метода:

1. issuperset() – возвращает True, если первое множество является подмножеством второго, и False в обратном случае. Такой же результат можно получить с помощью операторов < (строгое подмножество) и <= (нестрогое подмножество):

        >>> set_a = {1, 2, 3}
>>> set_b = {4, 5, 1, 2, 3}
>>> print(set_a.issubset(set_b))
True
>>> print(set_a <= set_b)
True
>>> print(set_a < set_b)
True

    

2. issubset() – возвращает True, если одно множество является надмножеством другого, и False в противном случае. Аналог – операторы > (строгое надмножество) и >= (нестрогое надмножество):

        >>> set_a = {'XS', 'S', 'M', 'L', 'XL', 'XXL'}
>>> set_b = {'S', 'M', 'L'}
>>> print(set_a.issuperset(set_b))
True
>>> print(set_a > set_b)
True
>>> print(set_a >= set_b)
True

    

3. isdisjoint() – возвращает True, если множества не имеют общих элементов, и False, если такие элементы есть:

        >>> set_a = {1, 2, 3}
>>> set_b = {4, 5, 6}
>>> set_c = {1, 3, 5}
>>> print(set_a.isdisjoint(set_b))
True
>>> print(set_c.isdisjoint(set_b))
False

    

Практика

Задание 1

Напишите программу, которая получает на вход три слова и определяет, являются ли они анаграммами друг друга.

Пример ввода:

        кластер
стрелка
сталкер

    

Вывод:

        Да
    

Решение:

        set_a, set_b, set_c = set(input()), set(input()), set(input())
print('Да' if set_a == set_b == set_c else 'Нет')

    

Задание 2

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

Пример ввода:

        кино книги велосипед хоккей кулинария цветы кошки
кошки кино путешествия футбол кулинария автомобили дайвинг

    

Вывод:

        Совпадение интересов: 27.27%
    

Решение:

        hobbies1 = input().split()
hobbies2 = input().split()
result = len(set(hobbies1) & set(hobbies2)) / float(len(set(hobbies1) | set(hobbies2))) * 100
print(f'Совпадение интересов: {result:.2f}%')

    

Задание 3

Напишите программу, которая получает на вход строку, и определяет, является ли строка панграммой (т.е. содержатся ли в ней все 33 буквы русского алфавита).

Пример ввода:

        Широкая электрификация южных губерний даст мощный толчок подъёму сельского хозяйства
    

Вывод:

        Да
    

Решение:

        result = {i.lower() for i in input() if i.isalpha()}
print('Да' if len(result) == 33 else 'Нет')

    

Задание 4

Напишите программу, которая получает n слов, и вычисляет количество уникальных символов во всех словах.

Пример ввода:

        5
программа
код
компьютер
монитор
интерпретатор

    

Вывод:

        Количество уникальных символов во всех словах: 14
    

Решение:

        n = int(input())
print('Количество уникальных символов во всех словах:', len(set(''.join([input().lower() for _ in range(n)]))))

    

Задание 5

Напишите программу, которая:

  • Получает на вход две строки, в которых перечисляются книги, прочитанные двумя учениками.
  • Выводит количество книг, которые прочитали оба ученика.

Пример ввода:

        Мастер и Маргарита, Война и мир, Тихий Дон, Евгений Онегин
Джейн Эйр, Террор, Война и мир, Мастер и Маргарита, Нос

    

Вывод:

        2
    

Решение:

        print(len(set(input().split(', ')) & set(input().split(', '))))
    

Задание 6

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

Пример ввода:

        4 12 6 11 0 8 7 5 1 25
2 1 4 5 56 6 8 7 14 33

    

Вывод:

        1 4 5 6 7 8
    

Задание 7

Напишите программу, которая получает два числа и выводит Есть, если числа содержат общие цифры, и Нет в противном случае.

Пример ввода:

        5678
3421

    

Вывод:

        Нет
    

Решение:

        print('Есть' if set(input()) & set(input()) else 'Нет')
    

Задание 8

Напишите программу, которая получает строку с именами файлов, и выводит уникальные имена .jpg файлов, отсортированные в алфавитном порядке.

Пример ввода:

        book_cover.jpg cover.png Book_cover.jpg illustration.jpg ILLUSTRATION.JPG my_cover.png photo.gif award.jpg Award.jpg award.JPG
    

Вывод:

        award.jpg book_cover.jpg illustration.jpg
    

Решение:

        files = input().split()
result = {i.lower() for i in files if i.lower().endswith('.jpg')}
print(*sorted(result))

    

Задание 9

Два дизайнера поспорили о том, кто из них знает больше оттенков цветов. Они перечисляют оттенки, но иногда забывают о том, что уже называли какой-то тон. Напишите программу, которая получает на вход n строк с названиями оттенков, и определяет, есть ли среди них повторы. Если повтор есть, нужно вывести Повтор, если нет – Принято.

Пример ввода:

        6
аспидно-серый
Бананомания
аквамариновый
Баклажановый
агатовый
антрацитовый

    

Вывод:

        Принято
    

Решение:

        colors = [input().lower() for _ in range(int(input()))]
print('Повтор!' if len(colors) > len(set(colors)) else 'Принято')

    

Задание 10

Кондитер собирается испечь торт. Напишите программу, которая поможет определить, имеются ли в кладовой все необходимые продукты:

  • Сначала программа получает список из m продуктов, которые есть в кладовой.
  • Затем получает n ингредиентов, необходимых для рецепта.
  • Выводит Есть, если ингредиент имеется в кладовой, и Отсутствует в противном случае.

Пример ввода:

        6
5
мука
сахар
Сода
яйца
масло сливочное
масло растительное
Сахар
Мука
Яйца
сливки
масло сливочное

    

Вывод:

        Есть
Есть
Есть
Отсутствует
Есть

    

Решение:

        m, n = [int(input()) for _ in 'mn']
pantry = {input().lower() for _ in range(m)}
[print('Есть' if input().lower() in pantry else 'Отсутствует') for _ in range(n)]

    

Подведем итоги

Множества позволяют просто и лаконично решать задачи, связанные с уникальностью, вхождением элементов в определенные группы и совпадением (расхождением) в составе групп. Однако множества в Python имеют серьезный недостаток – они занимают значительный объем памяти, что может стать проблемой при решении олимпиадных задач. В следующей статье будем изучать цикл for.

Содержание самоучителя

  1. Особенности, сферы применения, установка, онлайн IDE
  2. Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
  3. Типы данных: преобразование и базовые операции
  4. Методы работы со строками
  5. Методы работы со списками и списковыми включениями
  6. Методы работы со словарями и генераторами словарей
  7. Методы работы с кортежами
  8. Методы работы со множествами
  9. Особенности цикла for
  10. Условный цикл while
  11. Функции с позиционными и именованными аргументами
  12. Анонимные функции
  13. Рекурсивные функции
  14. Функции высшего порядка, замыкания и декораторы
  15. Методы работы с файлами и файловой системой
  16. Регулярные выражения
  17. Основы скрапинга и парсинга
  18. Основы ООП: инкапсуляция и наследование
  19. Основы ООП – абстракция и полиморфизм
  20. Графический интерфейс на Tkinter

Понравилась статья? Поделить с друзьями:
  • Как в контакте найти опросы
  • Как найти истинную конъюгату акушерство
  • Как найти отношение длины двух отрезков
  • Как найти очередь по списку
  • Thread 1 signal sigabrt swift как исправить