Вы не можете избежать этого, используя defaultdict
, поскольку это в его основной реализации:
class defaultdict:
@staticmethod
def __new__(cls, default_factory=None, **kwargs):
# Some code (e.g. urllib.urlparse) expects that basic defaultdict
# functionality will be available to subclasses without them
# calling __init__().
self = super(defaultdict, cls).__new__(cls)
self.d = {}
return self
def __init__(self, default_factory=None, **kwargs):
self.d = kwargs
self.default_factory = default_factory
def __getitem__(self, key):
try:
return self.d[key]
except KeyError:
v = self.__missing__(key)
self.d[key] = v
return v
def __setitem__(self, key, v):
self.d[key] = v
def __delitem__(self, key):
del self.d[key]
def __contains__(self, key):
return key in self.d
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
return self.default_factory()
Вы можете ясно видеть здесь
def __getitem__(self, key):
try:
return self.d[key]
except KeyError:
v = self.__missing__(key)
self.d[key] = v
return v
Это после получения значения по умолчанию для отсутствующий ключ, он регистрирует ключ, который вы пробовали в диктовке.
Это действительно важно в случае, например, при наличии карты списка:
from collections import defaultdict
list_map = defaultdict(list)
list_map['some_key'].append(5)
print(list_map['some_key'])
выведет:
[5]
здесь вы можете видеть, что я пытаюсь получить новый ключ, и в то же время я хочу добавить новый элемент в список, на который ссылается этот ключ, в вашем предложении, которое будет недействительным, поскольку вы возвращайте мне пустой список по умолчанию каждый раз, когда он связан с Nothing.
в вашей реализации он будет выводить вместо
[]
Вы можете изменить реализацию, если хотите, это небольшое изменение, но Вы должны рассчитывать на последствия ваших изменений.