import collections
a = collections.defaultdict(lambda: 3)
a.update({'one':1,'two':2})
print a['three']
3
emittiert je nach Bedarf. Sie könnten auch dict
selbst Unterklasse und überschreiben __missing__
, aber das macht nicht viel Sinn machen, wenn das defaultdict
Verhalten (die genaue fehlenden Schlüssel zu ignorieren, die nachgeschlagen Sein) zu Ihnen passt so gut ...
bearbeiten ... , es sei denn, Sie sind besorgt um a
wächst um einen Eintrag jedes Mal, wenn Sie einen fehlenden Schlüssel (der Teil der Semantik defaultdict
ist) suchen und lieber langsamer Verhalten, aber etwas Speicher sparen. Zum Beispiel in Bezug auf Speicher ...:
>>> 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
... die defaultdict, ursprünglich leer, jetzt hat die 99 zuvor fehlende Schlüssel, die wir nachgeschlagen, und nimmt 6284 Bytes (im Vergleich zu dem 140 Bytes es dauerte, als es leer war).
Der alternative Ansatz ...:
>>> 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
... speichert völlig diesen Speicher-Overhead, wie Sie sehen. Natürlich ist die Leistung ein weiteres Problem:
$ 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
Seit defaultdict
fügt die (bisher fehlenden) Taste auf Lookup, es viel schneller wird, wenn ein solcher Schlüssel nächsten nachgeschlagen, während mydict
(die __missing__
außer Kraft gesetzt, das zu vermeiden addition) zahlt jedes Mal den "fehlenden Key Lookup Overhead".
Ob Sie sich für ein Problem interessieren (Performance vs. Memory Footprint), hängt natürlich ganz von Ihrem speziellen Anwendungsfall ab. Es ist in jedem Fall eine gute Idee des Kompromisses zu beachten -)
'collections.defaultdict' ist Ihre Batterien inklusive Lösung. –
+1 für den Fragetitel –