Доброго времени суток, читатели, зрители моего канала programmer's notes. Не забывайте подписываться и писать свои комментарии к моим статьям и видео.
Библиотека collections как альтернатива встроенным коллекциям языка python. Компоненты: Counter, namedtuple, deque, defaultdict
Вернусь к базовому курсу по стандартным библиотекам. Сегодня стандартная библиотека collections. Она дополняет возможности встроенных в python коллекций. Хотя сама функциональность встроенных коллекций позволяет алгоритмически легко реализовать и возможности библиотеки collections, но эта библиотека даёт не только дополнительную функциональность, но и более высокую производительность. А это, при оперировании большими объёмами данных, может оказаться решающим аргументом. Весь материал по collections я разделил на два урока. Сегодня первый.
Класс Counter
Данный класс позволяет создавать словарь на основе подсчета элементов той или иной стандартной коллекции python.
Класс Counter удобен для подсчёта появлений каких-либо элементов в последовательностях. Он подсчитывает количество встречаемостей того или иного элемента в последовательности и указывает это количество в словаре, ключами которого являются как раз эти элементы.
Класс collections.Counter имеет те же методы, что и обычный класс dict, кроме того там есть методы:
- elements() — возвращает итератор элементов, в котором элемент встречается столько раз, сколько в исходной последовательности. Итератор, естественно может быть преобразован, например, в список (list()).
- most_common([n]) — возвращает список из n наиболее встречаемых элементов. Если n опущен или равен, то возвращаются все элементы. Из списка исключаются элементы у которых "количество" равно 0 или отрицательно.
- subtract() — вычитает значение счётчиков из соответствующих элементов.
Пример использования subtract() ниже
#!/usr/bin/python3
import collections as c
d1 = c.Counter({'a':2, 'b':3})
d2 = c.Counter({'a':1, 'b':1})
d1.subtract(d2)
print(d1)
Результат выполнения
Counter({'b': 2, 'a': 1})
Ещё один пример использования Counter()
#!/usr/bin/python3
import collections as c
# класса Counter - словарь
s = 'это очень очень очень очень длинная длинная строка'
cn1 = c.Counter(s)
print(cn1) # словарь количества букв в строке
# список букв в указанной строке
print(list(cn1.elements()))
# список пар: (буква, количество), если количество больше нуля
print(cn1.most_common())
# элемент 'C' в список не попадает
print(list(c.Counter({'A':2, 'B':3, 'C':-2}).elements()))
# аналогично работает с другими коллекциями
cn2 = c.Counter(s.split())
print(cn2) # словарь количества встречаемых слов
print(cn2.most_common())
Результат выполнения программы
Counter({'н': 8, ' ': 7, 'о': 6, 'ч': 4, 'е': 4, 'ь': 4, 'а': 3, 'т': 2, 'д': 2, 'л': 2, 'и': 2, 'я': 2, 'э': 1, 'с': 1, 'р': 1, 'к': 1})
['э', 'т', 'т', 'о', 'о', 'о', 'о', 'о', 'о', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'ч', 'ч', 'ч', 'ч', 'е', 'е', 'е', 'е', 'н', 'н', 'н', 'н', 'н', 'н', 'н', 'н', 'ь', 'ь', 'ь', 'ь', 'д', 'д', 'л', 'л', 'и', 'и', 'а', 'а', 'а', 'я', 'я', 'с', 'р', 'к']
[('н', 8), (' ', 7), ('о', 6), ('ч', 4), ('е', 4), ('ь', 4), ('а', 3), ('т', 2), ('д', 2), ('л', 2), ('и', 2), ('я', 2), ('э', 1), ('с', 1), ('р', 1), ('к', 1)]
['A', 'A', 'B', 'B', 'B']
Counter({'очень': 4, 'длинная': 2, 'это': 1, 'строка': 1})
[('очень', 4), ('длинная', 2), ('это', 1), ('строка', 1)]
Класс deque
Класс deque позволяет создавать двусторонние очереди. Конечно, создать двустороннюю. очередь можно и из обычного списка list. Но выполнение операций добавления элемента и удаления элемента требует определённого времени. Очереди от класса deque обладают более быстрыми методами.
В двухстороннею очередь можно не только добавлять элементы с конца (append()) но и в начало (appendleft()). Соответственно брать элементы модно, как и в обычном списке с конца (pop()) но и из начала (popoleft())
Пример работы с двусторонней очередью
#!/usr/bin/python3
import collections as c
# функция deque - двусторонняя очередь
dq = c.deque([3, 4, 1, 6, 8, 9, 11], None)
print(dq)
dq.append(1)
dq.appendleft(10)
print(dq)
print(dq.pop())
print(dq.popleft())
print(dq)
dq.insert(2, 111)
print(dq)
Результат выполнения
deque([3, 4, 1, 6, 8, 9, 11])
deque([10, 3, 4, 1, 6, 8, 9, 11, 1])
1
10
deque([3, 4, 1, 6, 8, 9, 11])
deque([3, 4, 111, 1, 6, 8, 9, 11])
Функция namedtuple
С помощью именованных кортежей можно присвоить имя каждому элементу в кортеже. Возможность ну в основном для улучшения читаемости. К элементам, однако можно обращаться и старым образом, используя индексы
#!/usr/bin/python3
import c/usr/bin/python3
import collections as c
# функция namedtuple() - именованные кортежи
grade = c.namedtuple('grade', ['number', 'count', 'year'])
gr1 = grade('7a', 30, 2024)
gr2 = grade('9г', 25, 2023)
print(gr1.number, gr1.count, gr1.year)
print(gr1[0], gr1[1], gr1[2])
gr2 = gr2._replace(count=20)
print(gr2.number, gr2.count, gr2.year)
Результат выполнения программы
7a 30 2024
7a 30 2024
9г 20 2023
Методом _replace(), как вы уже поняли, можно заменить соответствующий элемент в кортеже.
Класс defaultdict
Класс defaultdict это словарь со значением по умолчанию. Этот словарь обладает ещё одним удобным свойством. Если вы присваиваете что-то по значению ключа, которого ещё нет в словаре, то ключ просто добавляется с пустым или нулевым значением. Очень удобно.
Ниже представлена программа с такими словарями.
Результат выполнения программы
{'А': 2, 'Б': 2, 'В': 1, 'Г': 1, 'Д': 1, 'Е': 1, 'Ё': 3, 'К': 1, 'Л': 1}
{'Иванов': [1, 4, 1], 'Петров': [2, 4], 'Сидоров': [3]}
Отдельно отмечу, что для обычного словаря, если вы пытаетесь изменить значение по ключу, необходимо в начале проверить, есть такой ключ или нет (см. вот эту статью), и если нет, нужно будет добавить ключ со значением.
Пока всё! Следующий урок...
Пишите свои предложения и замечания, и занимайтесь программированием, а также проектированием баз данных, хотя бы для поддержания уровня интеллекта.