У цій статті ми розглянемо, як використовувати об’єкт лічильника з модуля колекцій Python.
Працюючи з великими послідовностями даних у Python, такими як списки або рядки, часто виникає потреба підрахувати кількість входжень кожного елемента.
Для цього підходить звичайний словник Python. Однак, клас `Counter` з модуля `collections` значно спрощує цю задачу, створюючи лічильник, що є словником, де ключами є елементи, а значеннями — їхня кількість.
Протягом наступних кількох хвилин ви дізнаєтеся:
- Як застосовувати об’єкт `Counter` у Python
- Як створити словник Python для відстеження кількості входжень елементів в ітерації
- Як спростити процес створення словника за допомогою `Counter`
- Як виконувати операції, такі як оновлення, віднімання елементів та пошук перетину між об’єктами `Counter`
- Як отримувати найчастіші елементи за допомогою методу `most_common()`.
Розпочнімо!
Модуль collections Python та клас Counter
Зазвичай, для підрахунку елементів в ітерації використовують словник Python, де ключами є самі елементи, а значеннями – кількість їхніх входжень.
Клас `Counter` знаходиться в модулі `collections`, тому для його використання потрібно імпортувати його:
from collections import Counter
Після імпортування можна створити екземпляр об’єкта `Counter` наступним чином:
<counter_object> = Counter(iterable)
Де:
- `iterable` – будь-який ітерований об’єкт Python, наприклад, список, рядок чи кортеж.
- Елементи в `iterable` мають бути хешованими.
Тепер, коли ми знаємо, як створювати об’єкти `Counter`, перейдемо до прикладів коду.
Приклади з цього посібника доступні на GitHub.
Як створити об’єкт Counter з ітерованих об’єктів Python
Розглянемо рядок “ренесанс” і назвемо його `word`.
>>> word = "renaissance"
Наша мета – створити словник, де кожна літера рядка буде ключем, а значенням – кількість її входжень. Можна скористатись циклом `for`:
>>> letter_count = {}
>>> for letter in word:
... if letter not in letter_count:
... letter_count[letter] = 0
... letter_count[letter] += 1
...
>>> letter_count
{'r': 1, 'e': 2, 'n': 2, 'a': 2, 'i': 1, 's': 2, 'c': 1}
Розберемо цей код:
- Спочатку створюється порожній словник `letter_count`.
- Далі відбувається ітерація по рядку `word`.
- Для кожної літери перевіряється, чи є вона вже в словнику.
- Якщо літери немає, вона додається до словника зі значенням 0, а потім збільшується на 1.
- Кожне входження літери збільшує її значення на 1.
- Цикл виконується, поки весь рядок не буде пройдено.
Ми створили словник `letter_count` вручну, використовуючи цикл.
Тепер використаємо клас `Counter` з модуля `collections`. Нам достатньо передати рядок `word` в `Counter()`, щоб отримати той самий результат:
>>> from collections import Counter
>>> letter_count = Counter(word)
>>> letter_count
Counter({'e': 2, 'n': 2, 'a': 2, 's': 2, 'r': 1, 'i': 1, 'c': 1})
`Counter` також є словником. Перевіримо це за допомогою `isinstance()`:
>>> isinstance(letter_count,dict)
True
Як бачимо, `isinstance(letter_count, dict)` повертає `True`, підтверджуючи, що `letter_count` є екземпляром класу `dict`.
Зміна об’єкта Counter
Наразі ми навчилися створювати об’єкти `Counter` з рядків.
Об’єкти `Counter` можна змінювати, оновлюючи їх елементами з іншого ітерованого об’єкта або віднімаючи елементи.
Оновлення Counter елементами з іншого ітерованого об’єкта
Ініціалізуємо інший рядок `another_word`:
>>> another_word = "effervescence"
Припустимо, нам потрібно оновити `letter_count` елементами з `another_word`.
Скористаємося методом `update()`:
>>> letter_count.update(another_word)
>>> letter_count
Counter({'e': 7, 'n': 3, 's': 3, 'c': 3, 'r': 2, 'a': 2, 'f': 2, 'i': 1, 'v': 1})
Результат показує, що `letter_count` оновився, включивши літери та їхню кількість з `another_word`.
Віднімання елементів з іншого ітерованого об’єкта
Тепер віднімемо значення `another_word` від `letter_count`. Використаємо метод `subtract()`. Метод `
Віднімемо `another_word` від `letter_count`.
>>> letter_count.subtract(another_word)
>>> letter_count
Counter({'e': 2, 'n': 2, 'a': 2, 's': 2, 'r': 1, 'i': 1, 'c': 1, 'f': 0, 'v': 0})
Значення, що відповідають літерам у `another_word`, віднялися, а додані ключі ‘f’ та ‘v’ не видалилися, а мають значення 0.
Примітка: тут ми передали рядок `another_word` до `subtract()`. Можна також передати інший об’єкт `Counter` або інший ітерований об’єкт.
Перетин між двома об’єктами Counter в Python
Іноді потрібно знайти перетин між двома об’єктами `Counter`, щоб визначити, які ключі є спільними.
Створимо об’єкт `letter_count_2` з рядка `another_word`, що дорівнює “effervescence”:
>>> another_word = "effervescence"
>>> letter_count_2 = Counter(another_word)
>>> letter_count_2
Counter({'e': 5, 'f': 2, 'c': 2, 'r': 1, 'v': 1, 's': 1, 'n': 1})
Використаємо оператор `&` для знаходження перетину між `letter_count` та `letter_count_2`:
>>> letter_count & letter_count_2
Counter({'e': 2, 'r': 1, 'n': 1, 's': 1, 'c': 1})
Зверніть увагу, що ми отримали ключі та кількість спільних входжень для двох слів. Обидва слова містять два повторення ‘e’ та по одному спільному входженню ‘r’, ‘n’, ‘s’ та ‘c’.
Знаходження найпоширеніших елементів за допомогою most_common
Ще одна поширена операція – пошук найчастіших елементів в об’єкті `Counter`.
Для отримання `k` найчастіших елементів можна використовувати метод `most_common()`. Викликаємо `most_common()` для `letter_count`, щоб знайти три літери, які зустрічаються найчастіше:
>>> letter_count.most_common(3)
[('e', 2), ('n', 2), ('a', 2)]
Ми бачимо, що літери ‘e’, ‘n’ та ‘a’ зустрічаються двічі у слові “ренесанс”.
Це особливо корисно, якщо лічильник містить велику кількість записів, і вас цікавлять найпоширеніші ключі.
Висновок
Ось основні висновки:
- Клас `Counter` з модуля `collections` можна використовувати для отримання словника підрахунку елементів у будь-якому ітераторі. Елементи в ітерації повинні бути хешованими.
- Можна оновити вміст одного об’єкта `Counter` іншим об’єктом `Counter` або будь-яким іншим ітерованим об’єктом за допомогою методу `update()`: `counter1.update(counter2)`. Замість `counter2` можна використати будь-який ітератор.
- Щоб видалити вміст одного з ітераторів, використовуйте метод `subtract()`: `counter1.subtract(counter2)`.
- Для пошуку спільних елементів між об’єктами `Counter` використовуйте оператор `&`. Для двох об’єктів `counter1` та `counter2`, вираз `counter1 & counter2` поверне перетин цих двох об’єктів.
- Для отримання `k` найпоширеніших елементів у `Counter` використайте метод `most_common()`: `counter.most_common(k)` поверне список з `k` найпоширеніших елементів і їхньою кількістю.
Далі розглянемо `defaultdict`, ще один клас у модулі `collections`. Використовуйте його замість звичайного словника для обробки відсутніх ключів.