HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-21
1 <p><a>#статьи</a></p>
1 <p><a>#статьи</a></p>
2 <ul><li>18 авг 2021</li>
2 <ul><li>18 авг 2021</li>
3 <li>0</li>
3 <li>0</li>
4 </ul><p>Не просто библиотека, а та самая библиотека.</p>
4 </ul><p>Не просто библиотека, а та самая библиотека.</p>
5 <p>Dana Moskvina / Skillbox Media</p>
5 <p>Dana Moskvina / Skillbox Media</p>
6 <p>Кандидат философских наук, специалист по математическому моделированию. Пишет про Data Science, AI и программирование на Python.</p>
6 <p>Кандидат философских наук, специалист по математическому моделированию. Пишет про Data Science, AI и программирование на Python.</p>
7 <p>Язык программирования Python, по сути, состоит из библиотек. Каждую из них можно установить, а затем импортировать в свой код и использовать как вам нужно. Наиболее полезные включаются в установку по умолчанию - они появляются на вашем компьютере вместе с собственно интерпретатором Python.</p>
7 <p>Язык программирования Python, по сути, состоит из библиотек. Каждую из них можно установить, а затем импортировать в свой код и использовать как вам нужно. Наиболее полезные включаются в установку по умолчанию - они появляются на вашем компьютере вместе с собственно интерпретатором Python.</p>
8 <p>Библиотека collections - одна из таких библиотек "из коробки". В ней содержатся мощные, удобные и быстродействующие альтернативы встроенным типам данных: словарям, спискам, кортежам.</p>
8 <p>Библиотека collections - одна из таких библиотек "из коробки". В ней содержатся мощные, удобные и быстродействующие альтернативы встроенным типам данных: словарям, спискам, кортежам.</p>
9 <p>Это может пригодиться в задачах подсчёта значений, организации сбора и быстрой конвертации данных из файлов CSV и баз SQL. Говорят, что разработчики и дата-сайентисты, открывшие для себя библиотеку collections, удивляются: "Как это я раньше жил без неё?"</p>
9 <p>Это может пригодиться в задачах подсчёта значений, организации сбора и быстрой конвертации данных из файлов CSV и баз SQL. Говорят, что разработчики и дата-сайентисты, открывшие для себя библиотеку collections, удивляются: "Как это я раньше жил без неё?"</p>
10 Изображение: Киностудия "Мосфильм"<p>Обычный словарь dict в Python содержит пары вида "ключ:значение". Значение из словаря можно запросить по ключу. В случае если запрашиваемого ключа в словаре нет, Python выдаст ошибку:</p>
10 Изображение: Киностудия "Мосфильм"<p>Обычный словарь dict в Python содержит пары вида "ключ:значение". Значение из словаря можно запросить по ключу. В случае если запрашиваемого ключа в словаре нет, Python выдаст ошибку:</p>
11 my_dict = {'a':1, 'b':2, 'c':3} my_dict['a'] &gt;&gt;&gt; 1 my_dict['d'] &gt;&gt;&gt; Traceback (most recent call last): &gt;&gt;&gt; File "&lt;pyshell#2&gt;", line 1, in &lt;module&gt; &gt;&gt;&gt; my_dict['d'] &gt;&gt;&gt; KeyError: 'd'<p>Поведение логичное, но не слишком удобное для работы. Словарь defaultdict из библиотеки collections поступает иначе: если запросить у такого продвинутого словаря ключ, которого в нём нет, он не обидится и не выкинет ошибку, а вместо этого:</p>
11 my_dict = {'a':1, 'b':2, 'c':3} my_dict['a'] &gt;&gt;&gt; 1 my_dict['d'] &gt;&gt;&gt; Traceback (most recent call last): &gt;&gt;&gt; File "&lt;pyshell#2&gt;", line 1, in &lt;module&gt; &gt;&gt;&gt; my_dict['d'] &gt;&gt;&gt; KeyError: 'd'<p>Поведение логичное, но не слишком удобное для работы. Словарь defaultdict из библиотеки collections поступает иначе: если запросить у такого продвинутого словаря ключ, которого в нём нет, он не обидится и не выкинет ошибку, а вместо этого:</p>
12 <ul><li>создаст этот ключ;</li>
12 <ul><li>создаст этот ключ;</li>
13 <li>создаст к нему значение, которое будет иметь тип, оговорённый по умолчанию ("по дефолту" - отсюда, кстати, и название), - например, целое число или строку;</li>
13 <li>создаст к нему значение, которое будет иметь тип, оговорённый по умолчанию ("по дефолту" - отсюда, кстати, и название), - например, целое число или строку;</li>
14 <li>и - тадамм! - вернёт вам это значение.</li>
14 <li>и - тадамм! - вернёт вам это значение.</li>
15 </ul><p>Строго говоря, в Python существуют стандартные методы словарей .setdefault() и .get() со сходной функциональностью, но они сложнее в использовании - надо каждый раз указывать значение по умолчанию. А здесь мы сразу задаём тип для всех таких значений и далее просто обращаемся по ключу.</p>
15 </ul><p>Строго говоря, в Python существуют стандартные методы словарей .setdefault() и .get() со сходной функциональностью, но они сложнее в использовании - надо каждый раз указывать значение по умолчанию. А здесь мы сразу задаём тип для всех таких значений и далее просто обращаемся по ключу.</p>
16 <p>Как это работает:</p>
16 <p>Как это работает:</p>
17 from collections import defaultdict my_new_dict = defaultdict(int, my_dict) my_new_dict &gt;&gt;&gt; defaultdict(&lt;class 'int'&gt;, {'a': 1, 'b': 2, 'c': 3}) my_new_dict['d'] &gt;&gt;&gt; 0 my_new_dict &gt;&gt;&gt; defaultdict(&lt;class 'int'&gt;, {'a': 1, 'b': 2, 'c': 3, 'd': 0})<p>В первой строчке импортировали модуль defaultdict из библиотеки collections.</p>
17 from collections import defaultdict my_new_dict = defaultdict(int, my_dict) my_new_dict &gt;&gt;&gt; defaultdict(&lt;class 'int'&gt;, {'a': 1, 'b': 2, 'c': 3}) my_new_dict['d'] &gt;&gt;&gt; 0 my_new_dict &gt;&gt;&gt; defaultdict(&lt;class 'int'&gt;, {'a': 1, 'b': 2, 'c': 3, 'd': 0})<p>В первой строчке импортировали модуль defaultdict из библиотеки collections.</p>
18 <p>Во второй - превратили наш предыдущий словарь my_dict в словарь нового типа my_new_dict: "int", стоящий первым в скобках, означает, что значениями, создаваемыми по умолчанию, будут целые числа, а конкретно число ноль.</p>
18 <p>Во второй - превратили наш предыдущий словарь my_dict в словарь нового типа my_new_dict: "int", стоящий первым в скобках, означает, что значениями, создаваемыми по умолчанию, будут целые числа, а конкретно число ноль.</p>
19 <p>Далее мы выводим наш my_new_dict, чтобы посмотреть, что в нём. Интерпретатор Python показывает нам:</p>
19 <p>Далее мы выводим наш my_new_dict, чтобы посмотреть, что в нём. Интерпретатор Python показывает нам:</p>
20 <ul><li>тип словаря: defaultdict;</li>
20 <ul><li>тип словаря: defaultdict;</li>
21 <li>тип значений по умолчанию: int;</li>
21 <li>тип значений по умолчанию: int;</li>
22 <li>а также текущее содержимое нашего словаря. Ключа "d" в нём нет, как и в оригинальном словаре my_dict.</li>
22 <li>а также текущее содержимое нашего словаря. Ключа "d" в нём нет, как и в оригинальном словаре my_dict.</li>
23 </ul><p>В следующей строке мы как раз и запрашиваем элемент с этим ключом. И, о чудо, my_new_dict выдаёт нам значение - оно равно 0.</p>
23 </ul><p>В следующей строке мы как раз и запрашиваем элемент с этим ключом. И, о чудо, my_new_dict выдаёт нам значение - оно равно 0.</p>
24 <p>Смотрим снова на содержимое нашего словаря и видим, что там появилась новая пара 'd': 0.</p>
24 <p>Смотрим снова на содержимое нашего словаря и видим, что там появилась новая пара 'd': 0.</p>
25 <p>Вы наверняка догадались, что вместо int при создании словаря типа defaultdict можно писать любые стандартные типы данных: float, list, str - и даже другие словари dict. И новые элементы, создаваемые при первом обращении к ключу, будут именно этого типа: нули, пустые списки, строки и словари соответственно.</p>
25 <p>Вы наверняка догадались, что вместо int при создании словаря типа defaultdict можно писать любые стандартные типы данных: float, list, str - и даже другие словари dict. И новые элементы, создаваемые при первом обращении к ключу, будут именно этого типа: нули, пустые списки, строки и словари соответственно.</p>
26 my_new_dict_2 = defaultdict(dict, my_dict) my_new_dict_2 &gt;&gt;&gt; defaultdict(&lt;class 'dict'&gt;, {'a': 1, 'b': 2, 'c': 3}) my_new_dict_2['e'] &gt;&gt;&gt; {} my_new_dict_2 &gt;&gt;&gt; defaultdict(&lt;class 'dict'&gt;, {'a': 1, 'b': 2, 'c': 3, 'e': {}})<p>И, конечно, словарь defaultdict поддерживает все<a>методы</a>обычных питоновских словарей: .items(), .values(), .keys() и другие.</p>
26 my_new_dict_2 = defaultdict(dict, my_dict) my_new_dict_2 &gt;&gt;&gt; defaultdict(&lt;class 'dict'&gt;, {'a': 1, 'b': 2, 'c': 3}) my_new_dict_2['e'] &gt;&gt;&gt; {} my_new_dict_2 &gt;&gt;&gt; defaultdict(&lt;class 'dict'&gt;, {'a': 1, 'b': 2, 'c': 3, 'e': {}})<p>И, конечно, словарь defaultdict поддерживает все<a>методы</a>обычных питоновских словарей: .items(), .values(), .keys() и другие.</p>
27 <p>Кортеж (tuple, его часто называют "неизменяемым списком") в Python содержит некоторое количество элементов, к каждому из которых можно обратиться только по его индексу.</p>
27 <p>Кортеж (tuple, его часто называют "неизменяемым списком") в Python содержит некоторое количество элементов, к каждому из которых можно обратиться только по его индексу.</p>
28 simple_tuple = (1, 'a', 123.4) simple_tuple[1] &gt;&gt;&gt; 'a'<p>Для простых задач этого хватает, но как только число элементов в кортеже начинает расти, их вызов по индексу становится головной болью, потому что существенно снижает читаемость кода.</p>
28 simple_tuple = (1, 'a', 123.4) simple_tuple[1] &gt;&gt;&gt; 'a'<p>Для простых задач этого хватает, но как только число элементов в кортеже начинает расти, их вызов по индексу становится головной болью, потому что существенно снижает читаемость кода.</p>
29 <p>Здесь снова приходит на помощь библиотека collections, а конкретно её функция namedtuple. Это расширение над встроенными кортежами, которое даёт имя каждому элементу кортежа, а точнее - создаёт именованные поля, в которые мы, как в строку в таблице, складываем значения.</p>
29 <p>Здесь снова приходит на помощь библиотека collections, а конкретно её функция namedtuple. Это расширение над встроенными кортежами, которое даёт имя каждому элементу кортежа, а точнее - создаёт именованные поля, в которые мы, как в строку в таблице, складываем значения.</p>
30 <p>В итоге получаем что-то вроде неизменяемого (immutable) словаря, только гораздо легче читаемого.</p>
30 <p>В итоге получаем что-то вроде неизменяемого (immutable) словаря, только гораздо легче читаемого.</p>
31 from collections import namedtuple fruit = namedtuple('fruit','number sort color') apple = fruit(number=5, sort='Antonovka', color='red') orange = fruit(number=7, sort='Navel Late', color='yellow')<p>Мы импортировали функцию namedtuple из collections. Затем создали конструктор именованных кортежей fruit, указав:</p>
31 from collections import namedtuple fruit = namedtuple('fruit','number sort color') apple = fruit(number=5, sort='Antonovka', color='red') orange = fruit(number=7, sort='Navel Late', color='yellow')<p>Мы импортировали функцию namedtuple из collections. Затем создали конструктор именованных кортежей fruit, указав:</p>
32 <ul><li>общее название тех кортежей, которые мы будем создавать ('fruit');</li>
32 <ul><li>общее название тех кортежей, которые мы будем создавать ('fruit');</li>
33 <li>строку, содержащую имена полей именованного кортежа. Имена разделены в строке пробелом.</li>
33 <li>строку, содержащую имена полей именованного кортежа. Имена разделены в строке пробелом.</li>
34 </ul><p>А после этого создали два именованных кортежа: apple и orange.</p>
34 </ul><p>А после этого создали два именованных кортежа: apple и orange.</p>
35 <p>Теперь можно обращаться к элементам этих кортежей не по индексу, а по именам полей number, sort и color. Они являются атрибутами именованных кортежей, то есть используются через точку и без скобок.</p>
35 <p>Теперь можно обращаться к элементам этих кортежей не по индексу, а по именам полей number, sort и color. Они являются атрибутами именованных кортежей, то есть используются через точку и без скобок.</p>
36 apple.sort &gt;&gt;&gt; 'Antonovka' orange.color &gt;&gt;&gt; 'yellow' # обращение по индексам работает по-прежнему apple[2] &gt;&gt;&gt; 'red'<p>Именованные кортежи обладают всеми свойствами простых кортежей, в том числе быстродействием и неизменяемостью, а также поддерживают их методы. В документации есть<a>хорошие примеры</a>использования.</p>
36 apple.sort &gt;&gt;&gt; 'Antonovka' orange.color &gt;&gt;&gt; 'yellow' # обращение по индексам работает по-прежнему apple[2] &gt;&gt;&gt; 'red'<p>Именованные кортежи обладают всеми свойствами простых кортежей, в том числе быстродействием и неизменяемостью, а также поддерживают их методы. В документации есть<a>хорошие примеры</a>использования.</p>
37 <p>Counter - это разновидность словаря Python, созданная для подсчёта, что понятно из названия. Ключами в ней выступают подсчитываемые элементы, а значениями - их количества. Посмотрим на примерах, как она работает.</p>
37 <p>Counter - это разновидность словаря Python, созданная для подсчёта, что понятно из названия. Ключами в ней выступают подсчитываемые элементы, а значениями - их количества. Посмотрим на примерах, как она работает.</p>
38 from collections import Counter # строки c = Counter('абвабббаввабббвавабг') print(c) &gt;&gt;&gt; Counter({'б': 8, 'а': 6, 'в': 5, 'г': 1}) # списки lst = [5,6,7,1,3,9,9,1,2,5,5,7,7] c = Counter(lst) print(c) &gt;&gt;&gt; Counter({5: 3, 7: 3, 1: 2, 9: 2, 6: 1, 3: 1, 2: 1})<p>Чаще всего в строке встречается буква "б" - 8 раз, а в списке - числа 5 и 7, по 3 раза. Подсчёт слов в предложении сводится к подсчёту элементов списка:</p>
38 from collections import Counter # строки c = Counter('абвабббаввабббвавабг') print(c) &gt;&gt;&gt; Counter({'б': 8, 'а': 6, 'в': 5, 'г': 1}) # списки lst = [5,6,7,1,3,9,9,1,2,5,5,7,7] c = Counter(lst) print(c) &gt;&gt;&gt; Counter({5: 3, 7: 3, 1: 2, 9: 2, 6: 1, 3: 1, 2: 1})<p>Чаще всего в строке встречается буква "б" - 8 раз, а в списке - числа 5 и 7, по 3 раза. Подсчёт слов в предложении сводится к подсчёту элементов списка:</p>
39 s = 'зима зима зима по полгода ни звоночка ни письма' words = s.split() # вернёт список слов Counter(words) &gt;&gt;&gt; Counter({'зима': 3, 'ни': 2, 'по': 1, 'полгода': 1, 'звоночка': 1, 'письма': 1})<p>Counter поддерживает все<a>методы словарей</a>плюс дополнительные методы elements() и most_common(n). Первый выдаёт список из элементов, количество которых больше нуля, а второй выводит список из n пар самых частых элементов в виде кортежей (элемент, количество).</p>
39 s = 'зима зима зима по полгода ни звоночка ни письма' words = s.split() # вернёт список слов Counter(words) &gt;&gt;&gt; Counter({'зима': 3, 'ни': 2, 'по': 1, 'полгода': 1, 'звоночка': 1, 'письма': 1})<p>Counter поддерживает все<a>методы словарей</a>плюс дополнительные методы elements() и most_common(n). Первый выдаёт список из элементов, количество которых больше нуля, а второй выводит список из n пар самых частых элементов в виде кортежей (элемент, количество).</p>
40 c = Counter(a=3, b=2, c=1, d=-2) # указали количества элементов sorted(c.elements()) &gt;&gt;&gt; ['a', 'a', 'a', 'b', 'b', 'c'] s = 'зима зима зима по полгода ни звоночка ни письма' words = s.split() Counter(words).most_common(2) # 2 самых частых элемента и их количество &gt;&gt;&gt; [('зима', 3), ('ни', 2)]<p>Типовые примеры использования Counter():</p>
40 c = Counter(a=3, b=2, c=1, d=-2) # указали количества элементов sorted(c.elements()) &gt;&gt;&gt; ['a', 'a', 'a', 'b', 'b', 'c'] s = 'зима зима зима по полгода ни звоночка ни письма' words = s.split() Counter(words).most_common(2) # 2 самых частых элемента и их количество &gt;&gt;&gt; [('зима', 3), ('ни', 2)]<p>Типовые примеры использования Counter():</p>
41 sum(c.values()) # сумма всех количеств c.clear() # сброс всех количеств list(c) # список элементов set(c) # преобразование во множество dict(c) # преобразование в обычный словарь c.items() # преобразование в список кортежей (элемент, количество) Counter(dict(list_of_pairs)) # обратное преобразование из списка кортежей вида (элемент, количество) c.most_common()[:-n-1:-1] # n самых редких элементов c += Counter() # удаление элементов с отрицательными и нулевыми количествами<p>Удобные инструменты из <a>библиотеки collections</a>помогут быстро разобраться с большим количеством однотипных данных: обработать их, преобразовать и передать дальше. Используйте collections везде, где требуется скорость работы, надёжный учёт данных и хорошая читаемость кода.</p>
41 sum(c.values()) # сумма всех количеств c.clear() # сброс всех количеств list(c) # список элементов set(c) # преобразование во множество dict(c) # преобразование в обычный словарь c.items() # преобразование в список кортежей (элемент, количество) Counter(dict(list_of_pairs)) # обратное преобразование из списка кортежей вида (элемент, количество) c.most_common()[:-n-1:-1] # n самых редких элементов c += Counter() # удаление элементов с отрицательными и нулевыми количествами<p>Удобные инструменты из <a>библиотеки collections</a>помогут быстро разобраться с большим количеством однотипных данных: обработать их, преобразовать и передать дальше. Используйте collections везде, где требуется скорость работы, надёжный учёт данных и хорошая читаемость кода.</p>
42 <p>На курсе "<a>Профессия Python-разработчик</a>" вы изучите и другие бриллианты из многочисленного семейства библиотек Python. Все они помогут вам в учёбе и дальнейшем трудоустройстве. Приходите!</p>
42 <p>На курсе "<a>Профессия Python-разработчик</a>" вы изучите и другие бриллианты из многочисленного семейства библиотек Python. Все они помогут вам в учёбе и дальнейшем трудоустройстве. Приходите!</p>
43 <a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
43 <a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>