Занятие 2

Лабораторное занятие 2

Множества (set)

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

In [1]:
a = {1, 2, 3}
a.add(4)
print(a)
{1, 2, 3, 4}
In [2]:
a.add(1)
print(a)
{1, 2, 3, 4}
In [3]:
print(0 in a, 1 in a)
False True

Для удаления элементов из множества можно использовать discard и remove, их поведение различается тогда, когда удаляемый элемент отсутствует в множестве: discard не делает ничего, а метод remove генерирует исключение KeyError, которое вы увидите в одной из ячеек ниже.

In [4]:
a.remove(1)
print(a)
{2, 3, 4}
In [5]:
a.remove(0)
print(a)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/tmp/ipython-input-3813938388.py in <cell line: 0>()
----> 1 a.remove(0)
      2 print(a)

KeyError: 0
In [ ]:
print(a)
In [ ]:
a.discard(2)
print(a)
In [ ]:
a.discard(0)
print(a)

Для создания пустого множества или для получения множества из итерируемого объекта можно использовать конструктор множеств set:

In [ ]:
a = set()
print(a)
a.add(1)
print(a)

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

In [ ]:
a = {}
print(a)
a.add(1)
print(a)
In [ ]:
a = [1, 2, 3, 4]
print(set(a))
In [ ]:
a = [1, 2, 3, 4, 1]
print(set(a))
In [ ]:
a = "abcd"
print(set(a))
In [ ]:
a = "abcda"
print(set(a))

Операции над множествами можно записывать как коротко символами, так и названиями соответствующих функций:

In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a.union(b))
print(a | b)
In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a.intersection(b))
print(a & b)
In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a.difference(b))
print(a - b)

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

In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a.symmetric_difference(b))
print(a ^ b)
In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a <= b)
print(a.issubset(b))

c = {3, 4}
d = {3, 4, 5, 6}
print(c <= d)
print(c.issubset(d))
In [ ]:
a = {3, 4, 5, 6}
b = {3, 4, 5, 6}
print(a <= b)
print(a < b)

Существуют также операции наподобие +=, -=, *=, /=, //=:

In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a &= b
print(a)
In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a.intersection_update(b)
print(a)
In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a |= b
print(a)
In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a.update(b)
print(a)
In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a -= b
print(a)
In [ ]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a.difference_update(b)
print(a)

Упражнение 0. Вывести на экран все элементы множества A, которых нет в множестве B. Дописать код ниже.

In [ ]:
A = set('bqlpzlkwehrlulsdhfliuywemrlkjhsdlfjhlzxcovt')
B = set('zmxcvnboaiyerjhbziuxdytvasenbriutsdvinjhgik')

Упражнение 1. Считать через input строку, состоящую из 3 слов и найти буквы, входящие в каждое из слов.

In [ ]:
 

Упражнение 2. Считать через input строку, состоящую из произвольного числа слов и найти буквы, входящие в каждое из слов.

In [ ]:
s = list(map(set, input().split()))
c = s[0]
for i in s:
    c.intersection_update(i)

Упражнение 3*. Считать через input несколько чисел через пробел и найти цифры, входящие в каждое из чисел. Использовать while.

In [ ]:
 

Словари (Dict)

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

In [ ]:
d = {"Россия": "Москва", "Франция": "Париж", "Германия": "Берлин"}
print(d["Германия"])

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

In [ ]:
d = dict()
d["Россия"] = "Москва"
print(d)

Можно обращаться к ключам словаря, к значениям словаря, итерировать по ключам и по парам ключ-значение.

In [ ]:
d = {"Россия": "Москва", "Франция": "Париж", "Германия": "Берлин"}
print(d.keys())
print(d.values())
In [ ]:
for k in d.keys():
    print(d[k])
In [ ]:
for k, v in d.items():
    print(k, v)
In [ ]:
print(d.items())
In [ ]:
print(list(d.items()))

Можем сортировать такие объекты, например, по странам в лексикографическом порядке:

In [ ]:
d = list(d.items())
d = sorted(d, key = lambda x: x[0])
print(d)

Set comprehensions. Dict comprehensions.

Можно генерировать множества и словари по аналогии со списками:

In [ ]:
a = [i for i in range(-5, 5)]
print(a)
a = {i for i in range(-5, 5)}
print(a)
a = [abs(i) for i in range(-5, 5)]
print(a)
a = {abs(i) for i in range(-5, 5)}
print(a)

Для определения порядкового номера символа в таблице символов ASCII используется функция ord:

In [ ]:
s = "a"
print(ord(s))
print(ord('A'), ord('Z'), ord('a'), ord('z'))

Обратная к ней функция, возвращающая символ по его порядковому номеру - chr:

In [ ]:
print(chr(65), chr(90), chr(97), chr(122))

Создадим словарь, состоящий из пар элементов номер буквы в таблице ASCII: буква.

In [ ]:
d = {i: chr(i) for i in range(65, 91)}
print(d)
print(d[70])

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

In [5]:
 

Упражнение 5. Создайте словарь, в котором каждой букве (как ключу) будет соответствовать ее порядковый номер в алфавите (значение). Рекомендация: использовать функции keys, values или items для словаря из предыдущего упражнения, чтобы создать новый.

In [5]:
 

Упражнение 6. Считайте слово с клавиатуры и найдите для него сумму номеров букв. Если некоторые буквы в слове повторяются (используйте такое слово), нужно считать только по уникальным буквам. Например, для строк 'abc' и 'abcbc' сумма будет 1+2+3=6, для xyz или zyxyz 24+25+26=75

In [5]:
 

Упражнение 7. Считайте с клавиатуры количество пар синонимов, затем сами пары синонимов, затем одно из слов среди этих пар. Выведите его синоним. Допишите код, заменив все TODO. Пример ввода:

3
Hello Hi
Bye Goodbye
List Array
Goodbye
In [6]:
n = int(input())
d = dict()
for i in range(n):
    s = input()
    # TODO completing a dictionary
s = input()
# TODO search for the desired synonym
1
1
2

Частотный анализ.

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

In [7]:
s = "abracadabra"
d = dict()
for i in s:
    if i in d:
        d[i] += 1
    else:
        d[i] = 1
print(d)
{'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}
In [8]:
print(s.count('a'))
print(d['a'])
5
5
In [9]:
s = "abracadabra" * 1000000
print(s[:100])
abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraa
In [10]:
import time
d = dict()
for i in s:
    if i in d:
        d[i] += 1
    else:
        d[i] = 1
t1 = time.time()
print(d['a'])
t2 = time.time()
print(t2 - t1)
5000000
0.0005633831024169922
In [11]:
t3 = time.time()
print(s.count('a'))
t4 = time.time()
print(t4 - t3)
5000000
0.033907175064086914

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

In [11]:
 

Collections.

Существуют также другие стандартные коллекции, которые позволяют решать некоторые задачи еще проще.

In [12]:
import collections
cnt = collections.Counter()
for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
    cnt[word] += 1
cnt
Out[12]:
Counter({'red': 2, 'blue': 3, 'green': 1})
In [13]:
cnt['red']
Out[13]:
2

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

In [14]:
from collections import Counter
c = Counter(a=4, b=2, c=0, d=-2)
print(sorted(c.elements()))
['a', 'a', 'a', 'a', 'b', 'b']
In [15]:
print(collections.Counter('abracadabra').most_common(3))
[('a', 5), ('b', 2), ('r', 2)]
In [16]:
c = Counter(a=4, b=2, c=0, d=-2)
d = Counter(a=1, b=2, c=3, d=4)
c.subtract(d)
print(c)
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
In [17]:
c = Counter(a=10, b=5, c=0)
c.total() # new for Python 3.10+
Out[17]:
15

С другими коллекциями вы можете познакомиться самостоятельно:

  1. https://pythonworld.ru/moduli/modul-collections.html
  2. https://docs.python.org/3/library/collections.html
In [17]: