import collections
a = collections.defaultdict(lambda: 3)
a.update({'one':1,'two':2})
print a['three']
испускает 3
по мере необходимости.Вы также можете создать подкласс dict
самостоятельно и переопределить __missing__
, но это не имеет особого смысла, когда поведение defaultdict
(игнорируя точный отсутствующий ключ, который ищется) подходит вам так хорошо ...
Редактировать ... , если , то есть вы беспокоитесь о том, что a
увеличивается на одну запись каждый раз, когда вы ищите отсутствующий ключ (который является частью defaultdict
семантика) и скорее получит более медленное поведение, но сэкономит память.Например, с точки зрения памяти ...:
>>> import sys
>>> a = collections.defaultdict(lambda: 'blah')
>>> print len(a), sys.getsizeof(a)
0 140
>>> for i in xrange(99): _ = a[i]
...
>>> print len(a), sys.getsizeof(a)
99 6284
... defaultdict, изначально пустой, теперь содержит 99 ранее отсутствующих ключей, которые мы искали, и занимает 6284 байта (по сравнению с140 байт потребовалось, когда он был пуст).
Альтернативный подход ...:
>>> class mydict(dict):
... def __missing__(self, key): return 3
...
>>> a = mydict()
>>> print len(a), sys.getsizeof(a)
0 140
>>> for i in xrange(99): _ = a[i]
...
>>> print len(a), sys.getsizeof(a)
0 140
..., как вы видите, полностью экономит эту память.Конечно, производительность - это еще одна проблема:
$ python -mtimeit -s'import collections; a=collections.defaultdict(int); r=xrange(99)' 'for i in r: _=a[i]'
100000 loops, best of 3: 14.9 usec per loop
$ python -mtimeit -s'class mydict(dict):
> def __missing__(self, key): return 0
> ' -s'a=mydict(); r=xrange(99)' 'for i in r: _=a[i]'
10000 loops, best of 3: 92.9 usec per loop
Поскольку defaultdict
добавляет (ранее отсутствующий) ключ при поиске, он становится намного быстрее при следующем поиске такого ключа, тогда как mydict
(который переопределяет __missing__
, чтобы избежать этого сложения) каждый раз платит «накладные расходы на поиск недостающего ключа».
Если вы заботитесь о любой проблеме (производительность или объем памяти), конечно, полностью зависит от вашего конкретного варианта использования.Это - это в любом случае хорошая идея знать о компромиссе! -)