Простой Python. Современный стиль программирования (Любанович) - страница 80

>>>> periodic_table['Hydrogen'] = 1

>>>> periodic_table['Lead']

>0

>>>> periodic_table

>defaultdict(, {'Lead': 0, 'Hydrogen': 1})

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

>>>> from collections import defaultdict

>>>>

>>>> def no_idea():

>…·····return 'Huh?'

>…

>>>> bestiary = defaultdict(no_idea)

>>>> bestiary['A'] = 'Abominable Snowman'

>>>> bestiary['B'] = 'Basilisk'

>>>> bestiary['A']

>'Abominable Snowman'

>>>> bestiary['B']

>'Basilisk'

>>>> bestiary['C']

>'Huh?'

Вы можете использовать функции int(), list() или dict(), чтобы возвращать пустые значения по умолчанию: int() возвращает 0, list() возвращает пустой список ([]) и dict() возвращает пустой словарь ({}). Если вы опустите аргумент, исходное значение нового ключа будет равно None.

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

>>>> bestiary = defaultdict(lambda: 'Huh?')

>>>> bestiary['E']

>'Huh?'

Применение int — это один из способов создать ваш собственный прилавок:

>>>> from collections import defaultdict

>>>> food_counter = defaultdict(int)

>>>> for food in ['spam', 'spam', 'eggs', 'spam']:

>…·····food_counter[food] += 1

>…

>>>> for food, count in food_counter.items():

>…·····print(food, count)

>…

>eggs 1

>spam 3

В предыдущем примере, если бы food_counter был обычным словарем, а не defaultdict, Python генерировал бы исключение всякий раз, когда бы мы пытались увеличить элемент словаря food_counter[food], поскольку он был бы не инициализирован. Нам понадобилось бы сделать дополнительную работу, как показано здесь:

>>>> dict_counter = {}

>>>> for food in ['spam', 'spam', 'eggs', 'spam']:

>…·····if not food in dict_counter:

>…·········dict_counter[food] = 0

>…·····dict_counter[food] += 1

>…

>>>> for food, count in dict_counter.items():

>…·····print(food, count)

>…

>spam 3

>eggs 1

Подсчитываем элементы с помощью функции Counter()

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

>>>> from collections import Counter

>>>> breakfast = ['spam', 'spam', 'eggs', 'spam']

>>>> breakfast_counter = Counter(breakfast)

>>>> breakfast_counter

>Counter({'spam': 3, 'eggs': 1})

Функция most_common() возвращает все элементы в убывающем порядке или лишь те элементы, количество которых больше, чем заданный аргумент count:

>>>> breakfast_counter.most_common()

>[('spam', 3), ('eggs', 1)]

>>>> breakfast_counter.most_common(1)