Используя результаты ответа здесь , мы создаем новый класс, который подклассов defaultdict, и переопределяем его атрибут отсутствует , чтобы разрешить передачу ключа в default_factory:
from collections import defaultdict
class keydefaultdict(defaultdict):
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
else:
ret = self[key] = self.default_factory(key)
return ret
Теперь вы можете создать вид словаря, который вы ищете, выполнив следующее:
my_dict = keydefaultdict(lambda x: x)
Затем, когда вам нужно сделать сопоставление для ключей, которые не отображаются насами вы просто обновляете эти значения.
Сроки.
Подклассы defaultdict
:
%%timeit
my_dict = keydefaultdict(lambda x: x)
for num in some_numbers: my_dict[num] == num
Результаты:
4.46 s ± 71.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Понимание Dict
%%timeit
my_dict = {x: x for x in some_numbers}
for num in some_numbers: my_dict[num] == num
Результаты:
1.19 s ± 20.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Они становятся сопоставимыми, когда вам требуется приблизительно 17 доступа% от первоначальных значений.И лучше, если вам нужно меньше:
Доступ только к части исходных значений
Подклассы defaultdict
:
%%timeit
frac = 0.17
my_dict = keydefaultdict(lambda x: x)
for num in some_numbers[:int(len(some_numbers)*frac)]: my_dict[num] == num
Результаты:
770 ms ± 4.69 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Понимание Dict
%%timeit
frac = 0.175
my_dict = {x: x for x in some_numbers}
for num in some_numbers[:int(len(some_numbers)*frac)]: my_dict[num] == num
Результаты:
781 ms ± 4.03 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)