Рубрики
Без рубрики

defaultdicts: Никогда не проверяйте, появится ли ключ снова!

Обзор того, как использовать класс по умолчаниюДом, который предоставляется стандартной библиотекой Python. Теги с Python, стандартлибрибирным, по умолчаниюДиктом.

Изображение покрытия Romain Vignes на Unsplash.

Это падает, так что кажется, что идеальное время написать несколько сообщений о PSL. Нету, а не тыквенные специи Lattes – стандартная библиотека Python! Стандартная библиотека – это куча полезных модулей, которые поставляются в упаковке с Python (аккумуляторы включены!), Поэтому мало нагрузки на безопасность/обслуживание, понесенное, когда вы потяните их в свой код!

Как я наставнил людей, новым в Python на упражнениях, есть пара упражнений, которые делают большое использование Диктовы Отказ Вы можете знать их на других языках как хеш , hashmap или Словарь Отказ Что бы вы ни называете их, я говорю о типе данных, которые отображает одно значение, A ключ к другой ценности, обычно называемым как Значение Отказ

Эта структура данных действительно приятна для выбора конкретных предметов для чтения или записи их ключей. Обычно используется для маркировки и сбора данных, для использования случаев, таких как школьный рецептер, счетчик слова или в качестве замены объекта, с именованными полями (хотя в Python, есть несколько лучших вариантов, чем простые опции для этого. Но это еще одна статья).

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

grades = ["A", "A", "B", "C", "D", "C", "B", "C", "A", "C", "B"]

counter = dict()
for grade in grades:
    if grade in counter:
        counter[grade] += 1
    else:
        counter[grade] = 1

Вам нужно проверить, является ли это конкретное письмо в счетчик Dict, прежде чем пытаться добавить 1 к нему. В противном случае вы столкнетесь с ошибками!

Там это Обходной путь, который достаточно ясен и легко читать: наш друг Получить Отказ

for grade in grades:
    counter[grade] = counter.get(grade, 0) + 1

По умолчанию Dict.get (ключ) Возвращает Нет Если ключ не найден вместо поднятия KeyError Как обычно, Но Если вы добавите этот второй аргумент на Получить вызов вместо этого он вернет этот по умолчанию, позволяя вам обновить или создать ключ все в одной строке.

Но Райан, ты говоришь. Это похоже на ужасно Многие работы, чтобы сделать только для того, чтобы указать мне значение по умолчанию, когда ключ отсутствует! И ты прав!

Есть еще лучший способ.

Позвольте мне представить вас с Модуль коллекций Отказ Проверьте документацию. Там есть гораздо больше вкусностей (не в последнюю очередь, что является фактическим Счетчик класс, который заботится о нашей самой проблеме здесь. Но, опять же, это для другого общения PSL). В частности, мы смотрим на defaultdict класс. Вот как это помогает нам решить проблему выше.

from collections import defaultdict

counter = defaultdict(int)

for grade in grades:
    counter[grade] += 1

Вот как это работает. defaultdict Конструктор принимает один аргумент: функция (или другой Callable). Обратите внимание, что мы не вызов Аргумент функции ( int ), так что нет скобок после int. мы проходим функцию int сам.

В любое время по умолчанию используется ключ, который он не видел раньше, вместо поднятия KeyError , это вызывает эту функцию, которую вы дали, создает этот новый ключ внутри сама и помещает результат функционального вызова в качестве ценность пары. Магия вот что int Функция, которую вы обычно используете для преобразования строк или поплавки на целые числа, на самом деле возвращает 0 Когда вы не передаете это ничего.

>>> int("5")
5
>>> int()
0

Вы можете спросить себя, хорошо, другие примитивные конструкторы делают то же самое? Вы делаете пари твоего маленького патофоты, они делают!

>>> str()
''
>>> list()
[]
>>> float()
0.0
# And EVEN
>>> complex()
0j

Список На самом деле один много пригодится. Допустим, вы хотите положить вещи в мусорные вещества:

from collections import defaultdict

school_roster = defaultdict(list)

# Nico is in 2nd grade
school_roster[2].append("Nico")

# So is Lester
school_roster[2].append("Lester")

# Laura is in 5th grade
school_roster[5].append("Laura")

school_roster
# => defaultdict(list, {2: ['Nico', 'Lester'], 5: ['Laura']})

Но что, если вы хотите сделать пользовательский конструктор? Как я уже сказал, это работает с каким-либо вызываемым, который не принимает аргументов и не возвращает!

def happy_constructor():
    return ":)"

happy_dict = defaultdict(happy_constructor)

happy_dict["Ryan"]
# => ":)"

Чаще, хотя, если конструктор короткий, вы увидите его в лямбда Форма, которая является просто причудливым способом быстрого, короткого, сброшенного, анонимной функции.

happy_dict = defaultdict(lambda: ":)")
happy_dict["You"]
# => ":)"

Если ваш пользовательский класс не принимает никаких аргументов в его __init__ Метод, вы можете пройти в свой класс тоже.

class Dog:
    def __init__(self):
        self.treats = 0

    def woof(self):
        return "Woof!"

hotel_for_dogs = defaultdict(Dog)
hotel_for_dogs["Fifi"].woof()
# => "Woof!"

Есть много классных вещей, которые вы можете сделать с этим классом. У вас есть какие-нибудь крутые способы, которыми вы его использовали? Я хочу знать о них!

Первоначально опубликовано Assert_not Magic?

Оригинал: “https://dev.to/rpalo/defaultdicts-never-check-if-a-key-is-present-again-5hlp”